Architecture
When you add code to a Frigear app, it can go in the app itself, in a module or in a separate package. The wrong place makes it hard to reuse, or ties a module to one app. After this page you can decide where a piece of code belongs and what it may depend on.
Which one do I use?
| You are writing | Put it in | Read |
|---|---|---|
| A page or API that only your product needs | Your host app | Project structure |
| A feature another app could reuse | A new module under packages/ | Writing a module |
| A helper for several modules that is not Nuxt-specific | A package under packages/ | Four kinds of code |
| A decision about who may do what | A role, a policy or the authorization:before hook in your host app, never the module | Access control |
Terms
- Host app. The Nuxt app that installs Frigear modules and configures them.
- Module. A Nuxt module published as
@frigear-nu/<name>that adds one feature to a host app. - Base layer. The shared Nuxt layer a host app extends for config, interface defaults and content pages.
- Package. Any npm package in the repository, named in install and publish steps and for tooling that is not a module.
How it works
Four kinds of code
| Kind | Where it lives | What it is |
|---|---|---|
| Host app | apps/*, or apps/web in a starter | A deployable Nuxt app, such as the Frigear website app. It registers modules and adds what is specific to it. |
| Base layer | packages/base-layer | @frigear-nu/base: shared Nuxt config, interface defaults and content-driven pages for websites. |
| Module | packages/<module> | A Nuxt module for one feature, such as users or stripe. |
| Package | packages/* | Tooling and shared code that is not a Nuxt module, such as the CLI and the ESLint config. |
workspace:* protocol. Packages depend on each other with workspace:^, so published
versions are carets. Run every command from the repository root (Local development).What a host app does
A host app is thin. It lists the modules it wants, configures them, decides what the modules leave open, and adds its own pages and tables:
- Modules in
nuxt.config.ts. It lists only the modules it uses directly (Adding modules). - Policy. Modules ask the host app before they act. The host app decides who counts as staff, which roles an OAuth application accepts and which claims a token carries. It answers in Nitro hooks.
- Its own database columns. It extends module tables from
server/db/extend.<dialect>.tsand commits the migrations (Database extensions). - Its own pages and strings. A page at the same path as a module page replaces it. Any module string can be
overridden in the host app's
i18n/locales/<code>.json.
Dependencies point one way
A module declares the modules it needs, and Nuxt installs them in the right order. The chains are listed in How they fit together.
The rule underneath is that dependencies point one way:
authsits belowusers. It reaches users only through the user store thatusersregisters (AuthUserStore).module-kitdepends on no feature module, and almost every module depends on it.- Anything optional, such as menus or widgets, is an optional dependency and guarded. The module still works when it is absent.
Composing without importing
Modules rarely import each other's code. They add to each other through extension points:
- Registries, filled at build time. Registration order does not matter.
- Hooks, answered at run time. A module asks a question, such as
authorization:before, and the host app answers it. - Database extensions. A module adds columns to a table another module owns, without the owner knowing.
So you can install a module and get its pages, menu items, dashboard widgets and MCP tools without touching any other module.
Common mistakes
authorize instead, and let the host app's roles and the
authorization:before hook decide who holds it.auth never imports users, and reaches
users only through the user store. Follow the same rule and use an extension point instead of an import.Next steps
- Access control – see how a route learns who is calling and what they may do.
- Extension points – add pages, menus and widgets from a module.
- Modules – find the module that already does what you need.