Browse documentation
DOCS/Architecture

ExetJS Architecture

ExetJS is a small modular backend engine on top of Express and TypeScript.

Core rule

Every module is explicit:

export type ExetModule = {
  name: string;
  basePath?: string;
  dependsOn?: readonly string[];
  register: (ctx: ExetContext) => Promise<ExetModuleRegisterResult> | ExetModuleRegisterResult;
};

An HTTP module returns { router }; an infrastructure module can return { dispose } without a router. dispose is also allowed alongside a router.

Registration orders explicitly declared dependencies and validates missing dependencies, duplicate names and cycles before side effects. Startup failure closes successful resource registrations in reverse order. HTTP server startup waits for listening; server shutdown drains HTTP before disposing resources. Signal handling is configurable and defaults to enabled only when resource disposers exist.

No magic

ExetJS intentionally avoids:

Core packages

@exetjs/core   Runtime engine helpers and shared types
@exetjs/cli  Developer CLI and code templates

Generated app shape

Generated applications depend on @exetjs/core for the engine helpers and keep business code inside src/modules.

src/
├─ main.ts
├─ app.ts
├─ config/
├─ middlewares/
├─ modules/
└─ shared/

Internal DB development layer

tools/db-core is the single development source for shared DB behavior. It is outside the workspace packages and does not ship to consumers. Provider descriptors and native adapters produce standalone CLI templates at build time. The engine and CLI installer contain no closed list of database providers.

A new database is added as a new adapter directory following the same contract. See Database modules and the internal authoring guide in tools/db-core/README.md.