@maholan/nestjs-template
v1.0.2
Published
MHL NestJS Backend Template — NestJS + Prisma + PostgreSQL + Redis + JWT + Docker
Maintainers
Readme
@maholan/nestjs-template
Production-ready NestJS backend starter — scaffolds a full project with one command.
NestJS 11 · TypeScript · Prisma · PostgreSQL · Redis · JWT · Pino · Docker · Yarn 4
Quick Start
npx @maholan/nestjs-template my-app
cd my-appThe CLI automatically:
- Copies the template
- Sets
package.jsonname to your project name - Creates
.envfrom.env.example - Enables Corepack (Yarn 4)
- Runs
yarn install
If you want a repository immediately, run git init after scaffold.
Getting Started
# Start PostgreSQL + Redis
docker compose up -d
# Create database tables
yarn prisma:migrate:dev
# Seed admin user
yarn prisma:seed
# Start dev server (http://localhost:3000)
yarn start:devSwagger docs available at http://localhost:3000/api/docs (development only).
What's Included
Tech Stack
| Layer | Technology | | --------------- | ---------------------------------------- | | Framework | NestJS 11 | | Language | TypeScript (strict mode) | | Database | PostgreSQL 17 + Prisma ORM | | Cache | Redis 7 (ioredis + cache-manager + Keyv) | | Queues | BullMQ (Redis-backed) | | Auth | JWT (access + refresh tokens) + API Key | | Logging | Pino (structured JSON, file rotation) | | Docs | Swagger / OpenAPI (auto-generated) | | Compiler | SWC (fast builds) | | Package Manager | Yarn 4 (Berry) | | Container | Docker multi-stage build |
Security
- Helmet (CSP, HSTS, noSniff)
- CORS whitelist
- Rate limiting (ThrottlerGuard)
- Global auth guard (JWT + API Key +
@Public()bypass) - Role-based access control (
@Roles('ADMIN')) - bcryptjs password hashing (cost 12)
- Cookie-based refresh tokens (httpOnly, sameSite, secure)
- Input validation (whitelist + forbidNonWhitelisted)
- Request body limit (1 MB)
Project Structure
src/
├── main.ts # Bootstrap (security, CORS, versioning)
├── app.module.ts # Root module
├── common/ # Shared infrastructure
│ ├── decorators/ # @Public, @Roles, @CurrentUser, @RequestId, @ResponseMessage
│ ├── dto/ # Response envelope (7-field standard), pagination
│ ├── filters/ # AllExceptionsFilter
│ ├── guards/ # AuthGuard, RolesGuard, ApiKeyGuard
│ ├── interceptors/ # Transform, Timeout, Logging
│ ├── middleware/ # RequestId
│ ├── pipes/ # ZodValidationPipe
│ └── utils/ # toApiDatetime (ISO 8601 +00:00)
├── config/ # Zod-validated env config
├── modules/
│ ├── auth/ # Login, refresh, logout, /me
│ ├── users/ # CRUD users + roles
│ └── health/ # Liveness / readiness (Terminus)
├── prisma/ # PrismaModule (global)
└── redis/ # RedisModule (global)Scripts
| Command | Description |
| ------------------ | -------------------- |
| yarn start:dev | Watch mode |
| yarn start:debug | Debug with inspector |
| yarn build | Compile (SWC) |
| yarn start:prod | Run compiled output |
| yarn lint | ESLint with auto-fix |
| yarn format | Prettier |
| yarn test | Unit tests |
| yarn test:cov | Coverage report |
| yarn test:e2e | E2E tests |
Database
| Command | Description |
| ---------------------------- | ----------------------------- |
| yarn prisma:migrate:dev | Create & apply migration |
| yarn prisma:migrate:deploy | Apply pending migrations (CI) |
| yarn prisma:studio | Visual DB browser |
| yarn prisma:seed | Seed data |
| yarn prisma:generate | Generate Prisma client |
| yarn db:reset | Reset DB & re-seed |
Environment Variables
Copy .env.example to .env (done automatically by the CLI).
| Variable | Default | Description |
| --------------------- | ------------- | ----------------------------------------- |
| NODE_ENV | development | Environment |
| PORT | 3000 | Server port |
| APP_NAME | ai-hub | App name (used in logs) |
| DATABASE_URL | — | PostgreSQL connection string |
| REDIS_HOST | localhost | Redis host |
| REDIS_PORT | 6379 | Redis port |
| REDIS_PASSWORD | — | Redis password |
| CACHE_TTL | 5000 | Default cache TTL (ms) |
| JWT_SECRET | — | Min 32 chars (required in production) |
| JWT_ACCESS_EXPIRES | 15m | Access token TTL |
| JWT_REFRESH_EXPIRES | 7d | Refresh token TTL |
| CORS_ORIGINS | — | Allowed origins (comma-separated) |
| COOKIE_SECURE | false | true for HTTPS |
| THROTTLE_TTL | 60000 | Rate limit window (ms) |
| THROTTLE_LIMIT | 100 | Requests per window |
| LOG_DIR | ./logs | Log file directory |
Docker
Development (database only)
docker compose up -d # PostgreSQL + Redis
yarn prisma:migrate:dev
yarn start:devProduction
docker build -t my-app .
docker run -p 3000:3000 --env-file .env.production my-appThe Dockerfile uses a multi-stage build:
- Build stage — installs deps, generates Prisma client, compiles TypeScript
- Runtime stage — Node 22 Alpine, non-root user (
nestjs), tini init, health check - Migrations run automatically on container start via
docker-entrypoint.sh
Production Checklist
- [ ]
NODE_ENV=production - [ ]
JWT_SECRET— min 32 chars, not the dev default - [ ]
DATABASE_URL— points to production DB - [ ]
CORS_ORIGINS— actual frontend domain(s) - [ ]
COOKIE_SECURE=true(if behind HTTPS) - [ ] Redis is accessible
- [ ] Log directory is writable / mounted as volume
- [ ] Database migrations are up to date
