A production-ready NestJS monorepo template with pnpm workspace, implementing Domain-Driven Design (DDD) and Clean Architecture principles.
A production-ready NestJS monorepo template with pnpm workspace, implementing Domain-Driven Design (DDD) and Clean Architecture principles.
Nestify is a pnpm workspace for reusable NestJS backend API packages built around Domain-Driven Design. The repository keeps generic API framework capabilities in packages/* and includes a small order API under apps/api to show how those packages are composed in a real service.
The first rule of this repository is separation:
Nestify currently contains 18 publishable framework packages:
| Package | Responsibility |
|---|---|
@a3s-lab/ddd |
Framework-independent DDD primitives with validated entity identities, structural immutable value objects, read-only aggregate event snapshots, defensive audit timestamps, finite guards, and explicit Result states. |
@a3s-lab/cqrs |
Deterministic NestJS CQRS adapter for @a3s-lab/ddd events, with validated batches, ordered defaults, bounded parallelism, native batch delegation, and configurable module wiring. |
@a3s-lab/http |
Bounded API envelopes, business errors, strict validation, safe request ids, pagination, DTO serialization, collision-safe key transforms, configurable error handling/API versioning, and OpenAPI helpers. |
@a3s-lab/security |
Default-deny guard primitives, public/role/permission metadata, local/dev guard helpers, path validation, sensitive operation metadata, JWT helpers, and role-permission checks. |
@a3s-lab/observability |
Request tracking, privacy-aware bounded SQL/external-call collectors, cardinality-safe Prometheus metrics, reactive HTTP instrumentation, and timeout-bound dependency-aware health checks. |
@a3s-lab/logger |
Pino structured logging with default secret redaction, isolated async request context, bounded HTTP metadata, and a NestJS request interceptor. |
@a3s-lab/kysely |
Validated NestJS lifecycle integration for Kysely, PostgreSQL pool builders, external-instance ownership, and bounded SQL diagnostics. |
@a3s-lab/redisson |
Lifecycle-safe Redis caching and lock helpers with local single-flight loads, managed lock ownership, cluster-aware SCAN/UNLINK cleanup, validated options, and bounded shutdown. |
@a3s-lab/resilience |
Validated, cancellation-aware retry; concurrency-safe circuit breaking; single-flight cache; bounded sliding-window rate limiting; and ownership-safe distributed locks. |
@a3s-lab/bullmq |
Lifecycle-safe NestJS BullMQ module with SDK-typed options, multi-worker management, queue metrics, health checks, bounded shutdown, and explicit cleanup helpers. |
@a3s-lab/nats |
Lifecycle-safe NATS messaging with validated SDK options, connection single-flight, request-many helpers, owned subscriptions, JetStream acknowledgement policy, active health probes, and bounded shutdown. |
@a3s-lab/rustfs |
NestJS S3-compatible object storage with method-correct signed URLs, policy-backed POST forms, multipart uploads, health checks, and graceful client shutdown. |
@a3s-lab/etcd |
NestJS etcd module with key-value operations, coherent bounded config caching, shared watches, leases, compare-and-set, retries, health checks, and failure-isolated cleanup. |
@a3s-lab/clickhouse |
Validated official ClickHouse client integration with cancellable requests, typed query/insert helpers, bounded database-client pooling, health reporting, and deterministic shutdown. |
@a3s-lab/migrations |
Validated Kysely migration lifecycle, sync/async NestJS registration, fail-closed startup policy, and named non-transactional operations. |
@a3s-lab/files |
Safe object-key validation, bounded and compensating batch uploads, route policies, request parameter decorators, and NestJS upload interceptors. |
@a3s-lab/ai |
Strict NestJS lifecycle integration for @a3s-lab/code, including lazy validated loading, standard/named/worker sessions, disposable runs and streams, cancellation, and race-safe shutdown. |
@a3s-lab/sandbox |
NestJS integration for the first-party @a3s-lab/box SDK with native instances, guarded connection configuration, managed scopes, and bounded observable shutdown. |
The shared package list is dependency-ordered in scripts/core-packages.mjs. Build, test, pack, smoke install, and publish rehearsal commands all use that same list.
…
Each package also has its own README with install notes, examples, exports, and package boundaries.
apps/api is a reference NestJS API, not the framework itself. It demonstrates:
The API entry point sets the global prefix to /api and exposes Swagger at /api/docs. The order controller provides:
POST /api/orders
GET /api/orders
GET /api/orders/:id
POST /api/orders/:id/confirm
POST /api/orders/:id/cancel
When observability modules are registered, health and metrics routes are available under the same global prefix:
GET /api/health
GET /api/health/live
GET /api/health/ready
GET /api/metrics
GET /api/metrics/json
The published NestJS integration packages accept NestJS 10 and 11 peers. The workspace and sample API are built and tested against NestJS 11 and Express 5.
git clone https://github.com/A3S-Lab/nestify.git
cd nestify
pnpm install
cp .env.example .env
docker compose -f docker/docker-compose.yml up -d postgres redis
pnpm build
pnpm start:dev
Open:
http://localhost:3000/apihttp://localhost:3000/api/docshttp://localhost:3000/api/metricsYou can also start the Docker development service:
docker compose -f docker/docker-compose.yml up app
| Command | Purpose |
|---|---|
pnpm build |
Build every workspace project. |
pnpm build:api |
Build only the sample API. |
pnpm build:core |
Build all framework packages from the shared core package list. |
pnpm test |
Run all workspace tests. |
pnpm test:core |
Run framework package tests from the shared core package list. |
pnpm lint:check |
Check Biome lint rules. |
pnpm format:check |
Check Biome formatting. |
pnpm release:check |
Format, lint, build, test, pack, and verify every framework package. |
pnpm smoke:core-install |
Install packed framework package tarballs in a temporary consumer project, type-check imports, and run a Node import smoke test. |
pnpm release:publish:dry-run |
Run the full release check, smoke install, and dry-run publishing of the verified package tarballs. |
pnpm release:check is the main local confidence command for package work. It verifies:
@a3s-lab/* package dependenciespnpm release:publish:dry-run runs release:check, smoke:core-install, and dry-run publishing against the exact
tarballs that passed verification. The real publish command uploads those same artifacts rather than rebuilding from
the source directories.
Public package changes should be recorded with Changesets:
pnpm changeset
pnpm version-packages
pnpm release:publish:dry-run
pnpm release:publish
pnpm release:publish publishes the verified shared-core tarballs in dependency order, skips package versions that
already exist on the configured npm endpoint, and then creates Changesets git tags.
CI checks pull requests with pnpm changeset status --since=origin/, except Changesets-generated version
PRs. Release automation starts only after the CI workflow succeeds for the same current main commit; it opens or
updates a version PR when changesets are pending, and publishes after that version PR is merged. Publishing requires
an NPM_TOKEN secret with access to the @a3s-lab scope.
SecurityModule.register() installs the default-deny guard globally. Only @Public() routes bypass authentication;
protected routes require an explicit delegate unless the application deliberately disables global installation.drain processes jobs.No open issues yet, or sync has not completed.