CLI

Using the cem CLI

Install the command, scaffold a project, and shape it with flags — all from the terminal.

Install the CLI

The package name is create-express-modular, but the binary you use after installing is cem.

bash
# npm
npm install -g create-express-modular

# yarn
yarn global add create-express-modular

# pnpm
pnpm add -g create-express-modular

# bun
bun add -g create-express-modular

Verify the install:

bash
cem --version
cem --help

Scaffold a project

Run cem with a project name. The wizard asks for your ORM, validator, auth style, Docker and Swagger preferences.

bash
cem my-api

Then move into the project and start the dev server:

bash
cd my-api
npm install
cem dev

Open http://localhost:5000 to see the CEM welcome page and health route. Swagger docs are available at /docs.

Quick mode flags

Pass -y or --yes to skip the prompts and scaffold the recommended stack instantly.

bash
cem my-api -y

Quick mode defaults:

  • Database / ORM: Mongoose (MongoDB)
  • Validator: Zod
  • Auth: JWT with HTTP-only cookies
  • Docker files included
  • Swagger / OpenAPI 3.0 docs included

Override individual choices

bash
# Database / ORM
cem my-api -y --db prisma
cem my-api -y --db drizzle

# Validator
cem my-api -y --validator joi

# Skip optional features
cem my-api -y --no-auth
cem my-api -y --no-docker
cem my-api -y --no-swagger

# Auth token delivery
cem my-api -y --header     # Authorization header instead of cookies

# Package manager and git
cem my-api -y --pm pnpm    # force pnpm instead of auto-detection
cem my-api -y --no-git     # skip git init
cem my-api -y --no-install # scaffold files without installing deps

Everyday commands

After scaffolding, cem stays useful for adding and removing features.

CommandWhat it does
cem devStart the tsx dev server with hot reload.
cem buildRun architecture guards and compile TypeScript to dist/.
cem startRun the compiled production server with preflight checks.
cem checkTypecheck, lint (ESLint v10) and format in one pipeline.
cem fixAuto-fix ESLint issues and Prettier formatting.
cem ejectInline standalone scripts into package.json.
cem listList modules, middlewares, env vars and Swagger status.
cem add module TaskScaffold a Task module wired into the router.
cem add env JWT_SECRETAdd an env var to .env, .env.example and config.
cem add middleware rateLimitCreate a custom middleware file.
cem remove module TaskDelete the module and unwire it from routes.

Developer experience & performance

Redesigned Developer Console UI

Modern terminal interface built with pure ANSI escape sequences — featuring smooth spinners, colored box borders, status badges, and crystal-clear output with zero external terminal bloat.

Lazy-loaded subcommands

CLI modules (db generators, validators, auth, Docker scaffolds) load on demand only when invoked. Instantaneous CLI startup times whether checking version or running heavy builds.

CI/CD & testing infrastructure

The CLI is backed by an automated end-to-end testing suite and strict publishing controls:

  • Integration test suite (tests/cli.test.mjs): Automated tests verifying CLI help, versions, multi-stack scaffolding (Mongoose, Prisma, Drizzle), and module generation.
  • GitHub Actions matrix (.github/workflows/ci.yml): Cross-platform automated build and E2E test matrix across Node 18, 20, and 22 on every pull request and push.
  • Pre-publish enforcement: A strict prepublishOnly pipeline guarantees that every release is fully typechecked, tested, and built before publishing to npm.

What gets generated

A scaffolded my-api is a fully wired, domain-driven Express + TypeScript project.

my-api/
├── src/
│   ├── app/
│   │   ├── config/index.ts          # typed, centralized config
│   │   ├── config/swagger.ts        # OpenAPI generator (if enabled)
│   │   ├── errors/                  # AppError + global error handler
│   │   ├── middlewares/             # auth, rate-limit, error, 404, compression
│   │   ├── modules/                 # feature modules (auto-wired)
│   │   │   └── Auth/                # generated when auth is enabled
│   │   ├── routes/index.ts          # router registry
│   │   └── utils/                   # catchAsync, sendResponse, QueryBuilder...
│   ├── app.ts                       # Express app instance (compression pre-wired)
│   └── server.ts                    # DB connection pool + keep-alive listen
├── .env                             # local env values
├── .env.example                     # documented env template
├── cem-cli.json                     # CEM manifest (tracks stack & features)
├── cem-cli.schema.json              # JSON Schema for editor auto-complete
├── Dockerfile                       # multi-stage production image
├── docker-compose.yml               # local database + app orchestration
├── eslint.config.js                 # ESLint v10 flat config rules
├── .prettierrc                      # format rules
├── tsconfig.json                    # TypeScript config
└── package.json                     # deps + scripts

Next steps