Skip to main content
A module is a self-contained business domain — billing, catalog, order — that bundles its controllers, entities, services, and the rest of its artifacts behind one registration point. The module:create generator scaffolds that whole shell for you and wires it into the app, so you start writing domain logic instead of boilerplate. For a tour of what a module is and how the pieces fit together, see the module overview.

Command

ooneex module:create [options]
Run it with no flags to be prompted for the module name and the destination it registers into:
ooneex module:create
Or pass everything up front to create a module non-interactively:
# Create a "billing" module and register it into the app
ooneex module:create --name=billing --destination=app

# Name only — you'll be prompted for the destination
ooneex module:create --name=Catalog
The --name is normalized to PascalCase and a trailing Module suffix is stripped, so billing, Billing, and BillingModule all produce the same module.
OptionDescriptionDefault
--nameModule name (normalized to PascalCase, the Module suffix is stripped).Prompted if omitted
--destinationDestination module to register the new module into.Prompted if omitted
These are the only options. For the complete reference, see module:create.

What gets generated

The generator creates the module directory under modules/<name>/ and registers it so it’s live the moment the command finishes:
  • src/<PascalName>Module.ts — the module class, with empty controllers, entities, middlewares, cronJobs, and events arrays ready to fill.
  • package.json and tsconfig.json — the module’s own dependency and compiler config.
  • <name>.yml — the module config file.
  • tests/<PascalName>Module.spec.ts — a mirrored test file.
It also wires the module into the rest of the project:
  • Registers it into its destination. For the app destination it’s added to both AppModule and SharedModule; for any other destination it’s added to that destination module.
  • Adds the module’s path alias to the root tsconfig.json.
  • Adds the module scope to .commitlintrc.ts when that file is present.
For a full breakdown of the directory layout and each generated file, see module structure.

Filling the module

A fresh module is an empty shell — every array in <PascalName>Module.ts starts empty. The next step is to add the artifacts that make up a vertical slice of the domain: an entity, a repository, a service, and a controller, then any middleware, cron jobs, or events the domain needs. You don’t add these by hand — each artifact has its own generator that scaffolds the file and registers it back into the module. Reach for: See module composition for how the artifacts relate and the order to build them in. When you need to tear a module back down, remove reverses everything module:create registered.

Use with Claude and Codex

The generator ships a matching module:create skill. Unlike a single-artifact generator, this skill scaffolds the whole module and then drives the per-artifact create skills — entity, repository, service, controller, and anything else the domain calls for — to fill in the first vertical slice. It’s what your AI agent reaches for when you ask it to stand up an entire domain rather than one file. Initialize the skills once for your agent:
ooneex claude:init
Then ask Claude in natural language — it maps the request to module:create, scaffolds the module, and fills in the slice:
Prompt
Create a billing module with a subscription entity, a service to manage plans, and a controller to expose them.
For example, the prompt above maps to module:create --name=billing, then chains the entity, service, and controller generators to build out the new billing domain end to end. For the full command reference, see module:create.