> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ooneex.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a module

> Scaffold a new backend module and register it into your app with a single generator command.

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](/module/overview).

## Command

```bash theme={null}
ooneex module:create [options]
```

Run it with no flags to be prompted for the module name and the destination it registers into:

```bash theme={null}
ooneex module:create
```

Or pass everything up front to create a module non-interactively:

```bash theme={null}
# 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.

| Option          | Description                                                              | Default             |
| --------------- | ------------------------------------------------------------------------ | ------------------- |
| `--name`        | Module name (normalized to PascalCase, the `Module` suffix is stripped). | Prompted if omitted |
| `--destination` | Destination module to register the new module into.                      | Prompted if omitted |

These are the only options. For the complete reference, see [module:create](/cli/commands/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](/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:

* [controller:create](/cli/commands/controller-create) — HTTP and WebSocket route handlers.
* [service:create](/cli/commands/service-create) — the domain logic the controllers call into.

See [module composition](/module/composition) for how the artifacts relate and the order to build them in. When you need to tear a module back down, [remove](/module/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:

<Tabs>
  <Tab title="Claude">
    ```bash theme={null}
    ooneex claude:init
    ```

    Then ask Claude in natural language — it maps the request to `module:create`, scaffolds the module, and fills in the slice:

    ```text Prompt icon="terminal" wrap theme={null}
    Create a billing module with a subscription entity, a service to manage plans, and a controller to expose them.
    ```
  </Tab>

  <Tab title="Codex">
    ```bash theme={null}
    ooneex codex:init
    ```

    Then ask Codex in natural language — it maps the request to `module:create`, scaffolds the module, and fills in the slice:

    ```text Prompt icon="terminal" wrap theme={null}
    Create a billing module with a subscription entity, a service to manage plans, and a controller to expose them.
    ```
  </Tab>
</Tabs>

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](/cli/commands/module-create).
