Skip to main content
The @ooneex/module package organizes your application by feature, not by file type. A module is a single, domain-scoped unit — billing, catalog, order, auth — that groups everything that capability needs: controllers, entities, services and repositories, middleware, cron jobs, and events. Instead of spreading one feature across a controllers/ tree, an entities/ tree, and a services/ tree, you keep it together under modules/<name>/ and let the framework wire it into the running app.

Why modules

  • Vertical slices. Each module owns a whole business capability end to end, so the code you change for one feature lives in one place rather than scattered across the codebase.
  • Domain boundaries. Naming modules after the domain (billing, order, auth) makes ownership and intent obvious, and keeps unrelated features from leaking into each other.
  • Real packages. Every module is its own workspace package named @module/<name> with a path alias in the root tsconfig.json, so imports are explicit and boundaries are enforced.
  • One contract. A module exports a single ModuleType object — a predictable shape that lists exactly what the module contributes to the app.
  • Generated, not hand-wired. Artifact generators scaffold straight into a module’s src/, so adding a controller or service to a feature is one command, not a manual file dance.

How it works

A module is a value that satisfies ModuleType from @ooneex/module. Each field is a collection of the classes that the module contributes — the app reads these collections to register the feature.
export type ModuleType = {
  controllers: (ControllerClassType | SocketControllerClassType)[];
  entities: EntityClassType[];
  middlewares: MiddlewareClassType[];
  cronJobs: CronClassType[];
  events: EventClassType[];
};
Each field collects one kind of artifact for the domain:
FieldWhat it collects
controllersHTTP and WebSocket controllers that expose the module’s routes and handlers.
entitiesEntity classes that model the module’s data.
middlewaresMiddleware classes that intercept requests for this module.
cronJobsScheduled jobs the module runs on a timer.
eventsEvent classes the module emits or listens for.
Because the shape is fixed, every module reads the same way: open it and you see, at a glance, every route, entity, job, and event the feature owns.

Structure and composition

Modules live under modules/<name>/, each its own workspace package (@module/<name>) with a src/ directory and a path alias in the root tsconfig.json. Two core modules always exist and cannot be removed:
ModuleRole
appThe application root module.
sharedCross-cutting code shared across feature modules.
When you create a new module, you register it into a destination module. The app destination registers the new module into both AppModule and SharedModule, composing it into the running application. The result is a tree of feature modules that the app assembles from a small set of roots. See structure for the on-disk layout of a module and composition for how modules register into AppModule and SharedModule.

Lifecycle

A module moves through three phases: create it, fill it with artifacts, then remove it when the feature is retired. 1. Create. Scaffold a new module and choose its destination.
ooneex module:create
This generates modules/<name>/ as a workspace package, names it @module/<name>, adds its path alias to the root tsconfig.json, and registers it into the chosen destination module. 2. Fill with artifacts. Generate controllers, services, entities, middleware, and the rest straight into the module’s src/.
ooneex controller:create --module=billing
ooneex service:create --module=billing
ooneex entity:create --module=billing
Each generator writes its class into the right place under modules/<module>/src/ — for example modules/billing/src/middlewares/<Name>Middleware.ts — and you register it in the matching field of the module’s ModuleType. 3. Remove. Tear a module down when its feature is gone.
ooneex module:remove
The app and shared modules are permanent and cannot be removed.

Next steps