[{"data":1,"prerenderedAt":697},["ShallowReactive",2],{"navigation:en":3,"\u002Fblog\u002Fmodular-architecture-nuxt-layers-b2b":129},[4],{"title":5,"path":6,"stem":7,"children":8,"icon":10},"Nuxfire Docs","\u002Fdocs","docs\u002F0.index",[9,11],{"title":5,"path":6,"stem":7,"icon":10},"i-ph-squares-four-duotone",{"title":12,"path":13,"stem":14,"children":15,"icon":18},"Flow Videos","\u002Fdocs\u002Fflow-videos","docs\u002Fflow-videos\u002F0.index",[16,19,36,67,93],{"title":17,"path":13,"stem":14,"icon":18},"Serelius Flow Video","i-ph-video-camera-duotone",{"title":20,"icon":21,"path":22,"stem":23,"children":24,"page":35},"Getting Started","i-ph-rocket-launch-duotone","\u002Fdocs\u002Fflow-videos\u002Fgetting-started","docs\u002Fflow-videos\u002F1.getting-started",[25,30],{"title":26,"path":27,"stem":28,"icon":29},"Overview","\u002Fdocs\u002Fflow-videos\u002Fgetting-started\u002Foverview","docs\u002Fflow-videos\u002F1.getting-started\u002F0.overview","i-ph-play-circle-duotone",{"title":31,"path":32,"stem":33,"icon":34},"Global Features","\u002Fdocs\u002Fflow-videos\u002Fgetting-started\u002Fglobal-features","docs\u002Fflow-videos\u002F1.getting-started\u002F1.global-features","i-ph-gear-six-duotone",false,{"title":37,"icon":38,"path":39,"stem":40,"children":41,"page":35},"Pipeline","i-ph-film-strip-duotone","\u002Fdocs\u002Fflow-videos\u002Fpipeline","docs\u002Fflow-videos\u002F2.pipeline",[42,47,52,57,62],{"title":43,"path":44,"stem":45,"icon":46},"Phase 1 — Script","\u002Fdocs\u002Fflow-videos\u002Fpipeline\u002Fscript","docs\u002Fflow-videos\u002F2.pipeline\u002F1.script","i-ph-scroll-duotone",{"title":48,"path":49,"stem":50,"icon":51},"Phase 2 — Style & Identity","\u002Fdocs\u002Fflow-videos\u002Fpipeline\u002Fstyle-and-identity","docs\u002Fflow-videos\u002F2.pipeline\u002F2.style-and-identity","i-ph-palette-duotone",{"title":53,"path":54,"stem":55,"icon":56},"Phase 3 — Storyboard","\u002Fdocs\u002Fflow-videos\u002Fpipeline\u002Fstoryboard","docs\u002Fflow-videos\u002F2.pipeline\u002F3.storyboard","i-ph-image-duotone",{"title":58,"path":59,"stem":60,"icon":61},"Phase 4 — Videos","\u002Fdocs\u002Fflow-videos\u002Fpipeline\u002Fvideos","docs\u002Fflow-videos\u002F2.pipeline\u002F4.videos","i-ph-video-duotone",{"title":63,"path":64,"stem":65,"icon":66},"Phase 5 — Final Assembly","\u002Fdocs\u002Fflow-videos\u002Fpipeline\u002Ffinal-assembly","docs\u002Fflow-videos\u002F2.pipeline\u002F5.final-assembly","i-ph-scissors-duotone",{"title":68,"icon":69,"path":70,"stem":71,"children":72,"page":35},"Settings & Models","i-ph-sliders-duotone","\u002Fdocs\u002Fflow-videos\u002Fsettings-and-models","docs\u002Fflow-videos\u002F3.settings-and-models",[73,78,83,88],{"title":74,"path":75,"stem":76,"icon":77},"Settings","\u002Fdocs\u002Fflow-videos\u002Fsettings-and-models\u002Fsettings","docs\u002Fflow-videos\u002F3.settings-and-models\u002F0.settings","i-ph-sliders-horizontal-duotone",{"title":79,"path":80,"stem":81,"icon":82},"AI Models & Limits","\u002Fdocs\u002Fflow-videos\u002Fsettings-and-models\u002Fmodels-and-limits","docs\u002Fflow-videos\u002F3.settings-and-models\u002F1.models-and-limits","i-ph-cpu-duotone",{"title":84,"path":85,"stem":86,"icon":87},"Option Catalogs","\u002Fdocs\u002Fflow-videos\u002Fsettings-and-models\u002Fcatalogs","docs\u002Fflow-videos\u002F3.settings-and-models\u002F2.catalogs","i-ph-list-bullets-duotone",{"title":89,"path":90,"stem":91,"icon":92},"Pipeline Calibration","\u002Fdocs\u002Fflow-videos\u002Fsettings-and-models\u002Fcalibration","docs\u002Fflow-videos\u002F3.settings-and-models\u002F3.calibration","i-ph-gauge-duotone",{"title":94,"icon":95,"path":96,"stem":97,"children":98,"page":35},"Reference","i-ph-book-open-duotone","\u002Fdocs\u002Fflow-videos\u002Freference","docs\u002Fflow-videos\u002F4.reference",[99,104,109,114,119,124],{"title":100,"path":101,"stem":102,"icon":103},"Delivered Files","\u002Fdocs\u002Fflow-videos\u002Freference\u002Fdelivered-files","docs\u002Fflow-videos\u002F4.reference\u002F0.delivered-files","i-ph-folder-duotone",{"title":105,"path":106,"stem":107,"icon":108},"Supported Video Types","\u002Fdocs\u002Fflow-videos\u002Freference\u002Fvideo-types","docs\u002Fflow-videos\u002F4.reference\u002F1.video-types","i-ph-television-duotone",{"title":110,"path":111,"stem":112,"icon":113},"What the Tool Does NOT Do","\u002Fdocs\u002Fflow-videos\u002Freference\u002Flimitations","docs\u002Fflow-videos\u002F4.reference\u002F2.limitations","i-ph-prohibit-duotone",{"title":115,"path":116,"stem":117,"icon":118},"Business Models","\u002Fdocs\u002Fflow-videos\u002Freference\u002Fbusiness-models","docs\u002Fflow-videos\u002F4.reference\u002F3.business-models","i-ph-briefcase-duotone",{"title":120,"path":121,"stem":122,"icon":123},"FAQ & Glossary","\u002Fdocs\u002Fflow-videos\u002Freference\u002Ffaq-and-glossary","docs\u002Fflow-videos\u002F4.reference\u002F4.faq-and-glossary","i-ph-question-duotone",{"title":125,"path":126,"stem":127,"icon":128},"Technical and Architectural Audit","\u002Fdocs\u002Fflow-videos\u002Freference\u002Faudit","docs\u002Fflow-videos\u002F4.reference\u002F5.audit","i-ph-shield-check-duotone",{"id":130,"title":131,"author":132,"authorType":133,"body":134,"category":676,"date":677,"description":678,"extension":679,"image":680,"lang":681,"meta":682,"navigation":287,"ogImage":683,"path":684,"readTime":685,"seo":686,"stem":687,"tags":688,"translations":692,"updated":133,"__hash__":696},"blog\u002Fblog\u002Fmodular-architecture-nuxt-layers-b2b.md","Modular Architecture with Nuxt Layers: Organizing B2B Features Without a Spaghetti Monolith","Nuxfire Team",null,{"type":135,"value":136,"toc":668},"minimark",[137,141,157,160,165,168,202,213,223,225,232,239,475,477,484,490,615,622,624,628,652,655,664],[138,139,140],"p",{},"As a SaaS product grows, the complexity of its code tends to explode. Checkout components get mixed with authentication rules, admin screens share directories with regular user screens, and a change to the database model breaks three different screens without warning.",[138,142,143,144,148,149,152,153,156],{},"The ",[145,146,147],"strong",{},"Nuxt 4"," answer to this dilemma is called ",[145,150,151],{},"Nuxt Layers",". In ",[145,154,155],{},"Nuxfire",", we use Layers to build isolated modules that can be turned on or off with a single line of configuration.",[158,159],"hr",{},[161,162,164],"h2",{"id":163},"what-is-a-nuxt-layer","What Is a Nuxt Layer?",[138,166,167],{},"A Layer in Nuxt is a complete, self-contained package that can hold:",[169,170,171,184,190,196],"ul",{},[172,173,174,175,179,180,183],"li",{},"Pages (",[176,177,178],"code",{},"pages\u002F",") and layouts (",[176,181,182],{},"layouts\u002F",").",[172,185,186,187,183],{},"Accessible Vue components (",[176,188,189],{},"components\u002F",[172,191,192,193,183],{},"Server routes and tRPC procedures (",[176,194,195],{},"server\u002F",[172,197,198,199,183],{},"Drizzle ORM schema slices (",[176,200,201],{},"schema.ts",[138,203,204,205,208,209,212],{},"This means the ",[145,206,207],{},"Billing"," feature, for example, lives entirely inside ",[176,210,211],{},"layers\u002Fbilling\u002F",".",[214,215,220],"pre",{"className":216,"code":218,"language":219},[217],"language-text","layers\u002F\n├── admin\u002F          # Platform admin panel, MFA and audit logs\n├── billing\u002F        # Stripe plans, checkout, webhooks and customer portal\n├── teams\u002F          # B2B multi-tenancy, member invitations and granular RBAC\n└── notifications\u002F  # WebSocket hub with Durable Objects and SQLite history\n","text",[176,221,218],{"__ignoreMap":222},"",[158,224],{},[161,226,228,229],{"id":227},"the-layer-contract-nuxfiremanifest","The Layer Contract: ",[176,230,231],{},"@nuxfire\u002Fmanifest",[138,233,234,235,238],{},"For each layer to be truly modular without tight coupling, every layer exports a manifest using the shared ",[176,236,237],{},"defineLayerManifest()"," helper:",[214,240,244],{"className":241,"code":242,"language":243,"meta":222,"style":222},"language-typescript shiki shiki-themes material-theme-lighter github-light github-dark monokai","import { defineLayerManifest } from \"@nuxfire\u002Fmanifest\";\n\nexport default defineLayerManifest({\n  name: \"billing\",\n  description: \"Stripe subscription management, webhooks and customer portal\",\n  dependencies: [\"teams\"],\n  routes: [\"\u002Fbilling\", \"\u002Fbilling\u002Fplans\"],\n  navigation: {\n    title: \"Subscription & Billing\",\n    icon: \"i-ph-credit-card-duotone\",\n    path: \"\u002Fbilling\"\n  }\n});\n","typescript",[176,245,246,282,289,307,327,344,367,398,409,426,443,458,464],{"__ignoreMap":222},[247,248,251,255,259,263,266,269,273,276,279],"span",{"class":249,"line":250},"line",1,[247,252,254],{"class":253},"sRxSC","import",[247,256,258],{"class":257},"swvn1"," {",[247,260,262],{"class":261},"ss--_"," defineLayerManifest",[247,264,265],{"class":257}," }",[247,267,268],{"class":253}," from",[247,270,272],{"class":271},"siCPE"," \"",[247,274,231],{"class":275},"sLACW",[247,277,278],{"class":271},"\"",[247,280,281],{"class":257},";\n",[247,283,285],{"class":249,"line":284},2,[247,286,288],{"emptyLinePlaceholder":287},true,"\n",[247,290,292,295,298,301,304],{"class":249,"line":291},3,[247,293,294],{"class":253},"export",[247,296,297],{"class":253}," default",[247,299,262],{"class":300},"sD0ED",[247,302,303],{"class":261},"(",[247,305,306],{"class":257},"{\n",[247,308,310,314,317,319,322,324],{"class":249,"line":309},4,[247,311,313],{"class":312},"squCx","  name",[247,315,316],{"class":257},":",[247,318,272],{"class":271},[247,320,321],{"class":275},"billing",[247,323,278],{"class":271},[247,325,326],{"class":257},",\n",[247,328,330,333,335,337,340,342],{"class":249,"line":329},5,[247,331,332],{"class":312},"  description",[247,334,316],{"class":257},[247,336,272],{"class":271},[247,338,339],{"class":275},"Stripe subscription management, webhooks and customer portal",[247,341,278],{"class":271},[247,343,326],{"class":257},[247,345,347,350,352,355,357,360,362,365],{"class":249,"line":346},6,[247,348,349],{"class":312},"  dependencies",[247,351,316],{"class":257},[247,353,354],{"class":261}," [",[247,356,278],{"class":271},[247,358,359],{"class":275},"teams",[247,361,278],{"class":271},[247,363,364],{"class":261},"]",[247,366,326],{"class":257},[247,368,370,373,375,377,379,382,384,387,389,392,394,396],{"class":249,"line":369},7,[247,371,372],{"class":312},"  routes",[247,374,316],{"class":257},[247,376,354],{"class":261},[247,378,278],{"class":271},[247,380,381],{"class":275},"\u002Fbilling",[247,383,278],{"class":271},[247,385,386],{"class":257},",",[247,388,272],{"class":271},[247,390,391],{"class":275},"\u002Fbilling\u002Fplans",[247,393,278],{"class":271},[247,395,364],{"class":261},[247,397,326],{"class":257},[247,399,401,404,406],{"class":249,"line":400},8,[247,402,403],{"class":312},"  navigation",[247,405,316],{"class":257},[247,407,408],{"class":257}," {\n",[247,410,412,415,417,419,422,424],{"class":249,"line":411},9,[247,413,414],{"class":312},"    title",[247,416,316],{"class":257},[247,418,272],{"class":271},[247,420,421],{"class":275},"Subscription & Billing",[247,423,278],{"class":271},[247,425,326],{"class":257},[247,427,429,432,434,436,439,441],{"class":249,"line":428},10,[247,430,431],{"class":312},"    icon",[247,433,316],{"class":257},[247,435,272],{"class":271},[247,437,438],{"class":275},"i-ph-credit-card-duotone",[247,440,278],{"class":271},[247,442,326],{"class":257},[247,444,446,449,451,453,455],{"class":249,"line":445},11,[247,447,448],{"class":312},"    path",[247,450,316],{"class":257},[247,452,272],{"class":271},[247,454,381],{"class":275},[247,456,457],{"class":271},"\"\n",[247,459,461],{"class":249,"line":460},12,[247,462,463],{"class":257},"  }\n",[247,465,467,470,473],{"class":249,"line":466},13,[247,468,469],{"class":257},"}",[247,471,472],{"class":261},")",[247,474,281],{"class":257},[158,476],{},[161,478,480,481],{"id":479},"turning-modules-on-and-off-in-configts","Turning Modules On and Off in ",[176,482,483],{},"config.ts",[138,485,486,487,489],{},"Imagine you are building a lean product and you do not need the the billing module or the complex notification system. In Nuxfire, you control the modules in the root ",[176,488,483],{}," file:",[214,491,493],{"className":241,"code":492,"language":243,"meta":222,"style":222},"export const config = {\n  domain: \"yoursaas.com\",\n  layers: {\n    core: [\"teams\", \"notifications\", \"admin\"],\n    features: {\n      billing: false, \u002F\u002F Turn it off easily without breaking the build\n    }\n  }\n};\n",[176,494,495,513,529,538,575,584,601,606,610],{"__ignoreMap":222},[247,496,497,499,503,507,511],{"class":249,"line":250},[247,498,294],{"class":253},[247,500,502],{"class":501},"srJo8"," const",[247,504,506],{"class":505},"s91G_"," config",[247,508,510],{"class":509},"sGXK2"," =",[247,512,408],{"class":257},[247,514,515,518,520,522,525,527],{"class":249,"line":284},[247,516,517],{"class":312},"  domain",[247,519,316],{"class":257},[247,521,272],{"class":271},[247,523,524],{"class":275},"yoursaas.com",[247,526,278],{"class":271},[247,528,326],{"class":257},[247,530,531,534,536],{"class":249,"line":291},[247,532,533],{"class":312},"  layers",[247,535,316],{"class":257},[247,537,408],{"class":257},[247,539,540,543,545,547,549,551,553,555,557,560,562,564,566,569,571,573],{"class":249,"line":309},[247,541,542],{"class":312},"    core",[247,544,316],{"class":257},[247,546,354],{"class":261},[247,548,278],{"class":271},[247,550,359],{"class":275},[247,552,278],{"class":271},[247,554,386],{"class":257},[247,556,272],{"class":271},[247,558,559],{"class":275},"notifications",[247,561,278],{"class":271},[247,563,386],{"class":257},[247,565,272],{"class":271},[247,567,568],{"class":275},"admin",[247,570,278],{"class":271},[247,572,364],{"class":261},[247,574,326],{"class":257},[247,576,577,580,582],{"class":249,"line":329},[247,578,579],{"class":312},"    features",[247,581,316],{"class":257},[247,583,408],{"class":257},[247,585,586,589,591,595,597],{"class":249,"line":346},[247,587,588],{"class":312},"      billing",[247,590,316],{"class":257},[247,592,594],{"class":593},"s8HiA"," false",[247,596,386],{"class":257},[247,598,600],{"class":599},"ss7Ak"," \u002F\u002F Turn it off easily without breaking the build\n",[247,602,603],{"class":249,"line":369},[247,604,605],{"class":257},"    }\n",[247,607,608],{"class":249,"line":400},[247,609,463],{"class":257},[247,611,612],{"class":249,"line":411},[247,613,614],{"class":257},"};\n",[138,616,617,618,621],{},"The build script inspects this file and assembles the final composition in ",[176,619,620],{},"apps\u002Fapp\u002Fnuxt.config.ts"," 100% automatically.",[158,623],{},[161,625,627],{"id":626},"practical-benefits-for-teams-and-developers","Practical Benefits for Teams and Developers",[629,630,631,637,643],"ol",{},[172,632,633,636],{},[145,634,635],{},"Isolated Testability",": Each layer has its own unit and integration tests.",[172,638,639,642],{},[145,640,641],{},"Immediate Reuse",": Create a new product by copying only the layers you need.",[172,644,645,648,649,651],{},[145,646,647],{},"Ideal Context for AI",": When you ask an AI (Cursor, Claude Code) to edit the checkout, it only needs to read the files inside ",[176,650,211],{},", without loading thousands of irrelevant lines into memory.",[138,653,654],{},"Ready to transform your productivity and build on the right architecture from the start?",[138,656,657],{},[658,659,661],"a",{"href":660},"\u002F#pricing",[145,662,663],{},"Get immediate access to the Nuxfire source code and the VIP Group →",[665,666,667],"style",{},"html pre.shiki code .sRxSC, html code.shiki .sRxSC{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#F92672;--shiki-sepia-font-style:inherit}html pre.shiki code .swvn1, html code.shiki .swvn1{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .ss--_, html code.shiki .ss--_{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .siCPE, html code.shiki .siCPE{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sLACW, html code.shiki .sLACW{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sD0ED, html code.shiki .sD0ED{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .squCx, html code.shiki .squCx{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .srJo8, html code.shiki .srJo8{--shiki-light:#9C3EDA;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .s91G_, html code.shiki .s91G_{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF;--shiki-sepia:#F8F8F2}html pre.shiki code .sGXK2, html code.shiki .sGXK2{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .s8HiA, html code.shiki .s8HiA{--shiki-light:#FF5370;--shiki-default:#005CC5;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}",{"title":222,"searchDepth":284,"depth":284,"links":669},[670,671,673,675],{"id":163,"depth":284,"text":164},{"id":227,"depth":284,"text":672},"The Layer Contract: @nuxfire\u002Fmanifest",{"id":479,"depth":284,"text":674},"Turning Modules On and Off in config.ts",{"id":626,"depth":284,"text":627},"Software Engineering","2026-09-15","How to decouple Stripe billing, multi-tenant workspaces and the admin panel with Nuxt Layers and Bun monorepos to build clean, sustainable SaaS products.","md","\u002Fimages\u002Fblog\u002Fnuxt-layers-modular-b2b-en.svg","en",{},"\u002Fimages\u002Fblog\u002Fnuxt-layers-modular-b2b-en.png","\u002Fblog\u002Fmodular-architecture-nuxt-layers-b2b","8 min",{"title":131,"description":678},"blog\u002Fmodular-architecture-nuxt-layers-b2b",[151,689,690,691],"Modular Architecture","B2B SaaS","Clean Code",{"en":693,"pt-br":694,"es":695},"modular-architecture-nuxt-layers-b2b","arquitetura-modular-nuxt-layers-b2b","arquitectura-modular-nuxt-layers-b2b","amiWWRgdB3vMbdWpI3h110MKe780Yr1xgpIV9QeqOUo",1794055339886]