Scaffold a module
A module adds one feature, with its pages, routes, translations and tables, to any
host app that lists it in modules. This page is for module authors: it creates the
package, its folder layout and package.json. The helpers it uses are in Module Kit.
Create the package
From the repository root:
pnpm cli module:create my-module
pnpm install
The command downloads the Nuxt module starter into packages/my-module and names the package @frigear-nu/my-module.
Match the rest, such as tsconfig, build, tests and scripts, to a sibling like packages/events.
CLI lists the command's options.
dev:stub script, never a postinstall. A postinstall would be published and run in every
install. The root postinstall runs each package's dev:stub instead.Folder layout
packages/my-module/
├── src/
│ ├── module.ts the Nuxt module: meta, moduleDependencies, setup()
│ ├── types.ts ModuleOptions and the other public types
│ └── runtime/
│ ├── app/ components, composables, pages (client and SSR code)
│ ├── server/ routes, plugins, utils
│ │ └── db/ schema.sqlite.ts and schema.postgresql.ts
│ ├── i18n/lang/ da.json and en.json
│ └── utils/
│ ├── index.ts the `/utils` export: helpers other modules call in their setup()
│ └── api.ts the `/api` export: typed path builders for the module's routes
├── test/
│ ├── fixtures/<name>/ test fixtures: small Nuxt apps that install the module
│ └── *.test.ts
├── playground/ the playground
├── .release-it.json
└── package.json
The playground is a dev app for working on this one package, started with pnpm --filter @frigear-nu/my-module dev.
It is not a test fixture. Only the built dist/ is published, so keep everything a host app
needs under src/runtime.
package.json
Inside the repository, exports point at the TypeScript source. On publish, publishConfig swaps in the built files.
Add ./utils when other modules import helpers from yours, and ./api for your path builders.
{
"name": "@frigear-nu/my-module",
"type": "module",
"main": "./src/module.ts",
"exports": {
".": { "types": "./src/module.ts", "import": "./src/module.ts", "default": "./src/module.ts" },
"./utils": {
"types": "./src/runtime/utils/index.ts",
"import": "./src/runtime/utils/index.ts",
"default": "./src/runtime/utils/index.ts"
},
"./api": {
"types": "./src/runtime/utils/api.ts",
"import": "./src/runtime/utils/api.ts",
"default": "./src/runtime/utils/api.ts"
}
},
"publishConfig": {
"exports": {
".": { "types": "./dist/types.d.mts", "import": "./dist/module.mjs", "default": "./dist/module.mjs" },
"./utils": {
"types": "./dist/runtime/utils/index.d.ts",
"import": "./dist/runtime/utils/index.js",
"default": "./dist/runtime/utils/index.js"
},
"./api": {
"types": "./dist/runtime/utils/api.d.ts",
"import": "./dist/runtime/utils/api.js",
"default": "./dist/runtime/utils/api.js"
}
},
"main": "./dist/module.mjs",
"typesVersions": { "*": { ".": ["./dist/types.d.mts"] } }
},
"files": ["dist"]
}
Next steps
- Setup checklist – declare the dependencies and write
setup(). - Testing – add a test fixture before the module grows.