Skip to content
All projects

NestJS Production Starter

A starting point for new APIs: JWT with rotating refresh tokens, roles, Swagger, Docker, tests and CI.

Type
Side project
Tech stack
  • NestJS
  • JWT
  • Swagger
  • Docker
  • CI
Illustration of NestJS Production Starter

Why

Every backend needs the same groundwork: auth, validation, config, logging, migrations, API docs, containers and CI. Doing it properly takes days, and doing it in a hurry leads to shortcuts that hurt later. This starter is that groundwork, done once and tested, ready to clone and build on.

What's included

AreaIncluded
AuthJWT access tokens with rotating refresh tokens, passwords hashed with bcrypt
Roles@Roles('admin') guards and a @CurrentUser() decorator
ValidationA global ValidationPipe with class-validator DTOs, whitelisting and transformation
DatabasePostgreSQL with Prisma, migrations and a seed script
DocsSwagger/OpenAPI at /docs, including auth
ConfigTyped environment variables, validated at startup
ErrorsOne global exception filter with one consistent error shape
SecurityHelmet, CORS config and rate limiting with @nestjs/throttler
OperationsA /health endpoint for app and database, structured JSON logs with request IDs
TestsUnit tests with Jest, e2e tests with Supertest against a real test database
DeliveryMulti-stage Dockerfile, docker compose for app and Postgres, GitHub Actions for lint, type check, tests and build

Request flow

  1. ClientHTTP
  2. GuardsJWT · roles · throttle
  3. ValidationPipe
  4. Controllers
  5. Services
  6. PostgreSQLPrisma
Errors from any layer end up in the global exception filter, which returns one consistent response shape.

Choices worth explaining

Config is validated when the app starts. A missing secret stops it right away instead of causing odd errors in production.

Access tokens are short-lived. Refresh tokens are rotated and invalidated on logout. That's quick to describe and takes care to get right.

The e2e tests run against a separate, real database instead of mocks, because mocks hide problems with constraints and transactions.

The starter also provides the login for AgentDesk. Using it in a second project showed which parts actually need to be configurable.