Node API Starter
✨ Features
| Area | Capability |
|---|
| 🔐 Authentication | Register, login, access + refresh tokens, HTTPOnly cookies, mobile bearer-token support, logout, logout-all-devices |
| 🧾 Sessions | Device tracking, refresh token hashing & rotation, JWT versioning, MongoDB TTL-based session expiry |
| 🔑 Passwords | Forgot/reset password, Redis-backed reset tokens, password history, reuse prevention, strength rules |
| 📧 Verification | Email verification link, OTP send/verify with Redis expiry and rate limiting |
| 🛡️ RBAC | super_admin, admin, manager, employee, guest, user roles with centralized permissions |
| 🚦 Rate Limiting | Redis sliding-window limits for login, register, OTP, uploads, and general API traffic |
| 📦 Uploads | Local / S3 / Cloudinary storage, Sharp image optimization, multiple upload, signed URLs |
| 📚 API Docs | Full Swagger / OpenAPI spec at /api-docs |
| 🧭 Observability | Pino logger, request ID, correlation ID, trace ID, audit logs, OpenTelemetry APM |
| 🩺 Health Checks | /health, /health/live, /health/ready covering MongoDB, Redis, memory, CPU, and uptime |
| 🧪 Testing | Vitest + Supertest + MongoDB Memory Server |
| 🐳 Delivery | Production Dockerfile, dev Dockerfile, Docker Compose, GitHub Actions CI |
🧰 Tech Stack
| Layer | Technology |
|---|
| Runtime | Node.js 24 |
| Framework | Express 5 |
| Language | TypeScript (strict mode) |
| Database | MongoDB + Mongoose |
| Cache / Sessions | Redis |
| Validation | Zod |
| Auth | JWT, bcrypt, HTTPOnly cookies |
| Logging | Pino |
| APM | OpenTelemetry Node SDK, auto-instrumentation, OTLP traces and metrics |
| Security | Helmet, CSP, CORS, HPP, sanitization |
| Uploads | Multer, Sharp, AWS S3 SDK, Cloudinary |
| Docs | Swagger UI / OpenAPI |
| Testing | Vitest, Supertest, mongodb-memory-server |
| DevOps | Docker, Docker Compose, GitHub Actions |
🗂️ Project Structure
node-api-starter/
├── src/
│ ├── config/ # env, mongodb, redis, security, swagger, logger
│ ├── constants/ # roles, permissions, permission map
│ ├── libs/ # jwt, cookies, password, pagination, ApiResponse, AppError
│ ├── middlewares/ # auth, rbac, validation, rate limit, request context
│ ├── modules/
│ │ ├── auth/ # login, register, sessions, tokens, OTP
│ │ ├── user/ # profile & admin user management
│ │ ├── upload/ # local / S3 / Cloudinary uploads
│ │ ├── health/ # liveness & readiness checks
│ │ └── audit/ # audit log persistence
│ ├── routes/ # versioned API router (/api/v1)
│ └── types/ # Express type augmentation
├── tests/ # Vitest + Supertest suites
├── database/ # seed script
├── scripts/ # module generator / remover CLI
└── docs/ # full project documentation
📄 See docs/PROJECT_STRUCTURE.md for a file-by-file breakdown.
🏗️ Architecture at a Glance
graph LR
Client[Web / Mobile Client] -->|HTTP / Cookies / Bearer| Express[Express App]
Express --> Security[Security Middleware]
Security --> RateLimit[Redis Sliding Window]
RateLimit --> Routes["/api/v1 Routes"]
Routes --> Validation[Zod Validation]
Validation --> Auth[Auth + RBAC]
Auth --> Controller[Controller]
Controller --> Service[Service Layer]
Service --> Mongo[(MongoDB)]
Service --> Redis[(Redis)]
Service --> Storage[(Local / S3 / Cloudinary)]
Controller --> Response[ApiResponse]
Request → Route → Middleware → Controller → Service → Model → Database
🚀 Quick Start
git clone https://github.com/Abd2002/node-api-starter.git
cd node-api-starter
npm install
cp .env.example .env
Update .env with your own secrets and connection strings (see Environment Variables), then:
npm run dev
Your API will be running at:
http://localhost:3000/api/v1
Swagger docs at:
http://localhost:3000/api-docs
🔐 Environment Variables
Environment variables are validated with Zod at startup — the server fails fast if anything required is missing or invalid.
| Variable | Required | Description |
|---|
PORT | ✅ | HTTP server port |
MONGO_URI | ✅ | MongoDB connection string |
REDIS_URL | ✅ | Redis connection string |
JWT_SECRET / JWT_REFRESH_SECRET | ✅ | Token signing secrets (32+ chars) |
JWT_EXPIRES_IN / JWT_REFRESH_EXPIRES_IN | ✅ | Token lifetimes |
COOKIE_SECRET | ✅ | Signed-cookie secret (32+ chars) |
CLIENT_URL / FRONTEND_URL | ✅ | Allowed frontend origins |
SMTP_* | ✅ | Email delivery credentials |
S3_* / CLOUDINARY_* | ✅ (if used) | Upload provider credentials |
APM_* | No | OpenTelemetry APM configuration |
UPLOAD_PROVIDER | No | local | s3 | cloudinary (default local) |
Full reference: docs/ENVIRONMENT_VARIABLES.md
📖 API Overview
All responses follow a standard envelope:
{
"success": true,
"message": "Operation completed",
"data": {}
}
Auth
| Method | Endpoint | Description |
|---|
POST | /api/v1/auth/register | Register a new user |
POST | /api/v1/auth/login | Login and create a session |
POST | /api/v1/auth/refresh-token | Rotate refresh token |
POST | /api/v1/auth/logout | Revoke current session |
POST | /api/v1/auth/logout-all | Revoke all sessions |
POST | /api/v1/auth/forgot-password | Send reset link |
POST | /api/v1/auth/reset-password | Reset password by token |
POST | /api/v1/auth/change-password | Change current password |
POST | /api/v1/auth/otp/send / otp/verify | Email OTP flow |
Users
| Method | Endpoint | Roles |
|---|
GET | /api/v1/users/me | Any authenticated user |
GET | /api/v1/users | Admin, Super Admin |
PATCH | /api/v1/users/:id | Admin, Super Admin |
DELETE | /api/v1/users/:id | Admin, Super Admin |
Uploads & Health
| Method | Endpoint | Description |
|---|
POST | /api/v1/uploads?category=document | Upload a file |
GET | /api/v1/uploads/:id/signed-url | Get signed URL |
GET | /health | /health/live | /health/ready | Health checks |
📚 Full endpoint reference with request/response examples: docs/API_GUIDE.md
🛠️ Scripts
| Command | Description |
|---|
npm run dev | Start development server (hot reload) |
npm run build | Compile TypeScript to dist/ |
npm start | Run compiled production server |
npm run typecheck | Strict TypeScript checks |
npm run lint | Run ESLint |
npm run test:unit | Run Vitest test suite |
npm run test:unit:coverage | Run tests with coverage |
npm run seed | Seed baseline roles/users |
npm run create:module <name> | Scaffold a new module (routes, controller, service, model) |
npm run remove:module <name> | Remove a module |
🐳 Docker
# Production
docker build -t node-api-starter .
docker run --env-file .env -p 3000:3000 node-api-starter
# Development
docker build -f Dockerfile.dev -t node-api-starter-dev .
# Full stack (API + MongoDB + Redis)
docker compose up --build
🧪 Testing
npm run test:unit
npm run test:unit:coverage
Tests run against an isolated in-memory MongoDB instance via mongodb-memory-server, covering auth, users, uploads, rate limiting, health, and error handling.
📈 Application Performance Monitoring
APM is implemented with OpenTelemetry, which is the safest default for a production Node.js starter because it is vendor-neutral. The same instrumentation can export traces and metrics to an OpenTelemetry Collector, Datadog, New Relic, Honeycomb, Grafana Tempo, or another OTLP-compatible backend.
APM is disabled by default. Enable it with:
APM_ENABLED=true
APM_SERVICE_NAME=node-api-starter
APM_SERVICE_VERSION=1.0.0
APM_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces
APM_OTLP_METRICS_ENDPOINT=http://localhost:4318/v1/metrics
APM_OTLP_HEADERS=
APM_METRICS_ENABLED=true
APM_METRICS_INTERVAL_MS=60000
APM_TRACE_SAMPLE_RATIO=1
The APM bootstrap lives in src/config/apm.ts and is imported before the Express app starts, so HTTP, Express, MongoDB, Redis, and supported Node internals can be auto-instrumented.
Vendor examples:
| Vendor | Configuration |
|---|
| OpenTelemetry Collector | Point APM_OTLP_TRACES_ENDPOINT and APM_OTLP_METRICS_ENDPOINT to the collector OTLP HTTP receiver. |
| New Relic | Use New Relic's OTLP endpoint and set APM_OTLP_HEADERS=api-key=<license-key>. |
| Datadog | Send OTLP to a local Datadog Agent or collector and configure API keys at the agent/collector layer. |
🛡️ Security Highlights
- Helmet, CSP, CORS allowlist, HPP protection, request sanitization
- HTTPOnly + signed cookies, refresh token rotation and hashing
- Redis-backed access-token blacklist and JWT versioning
- bcrypt password hashing, password history, and reuse prevention
- Redis sliding-window rate limiting per endpoint risk level
- Zod validation on every request boundary
🔍 Full security posture: docs/SECURITY.md
📚 Documentation
🗺️ Roadmap
Planned next steps include audit-log query APIs, role/permission management endpoints, a background job queue, and API key authentication. See docs/ROADMAP.md for the full list.
🤝 Contributing
Contributions are welcome! Please read docs/CONTRIBUTING.md before opening a pull request — changes should preserve strict TypeScript, avoid duplicated infrastructure logic, and include tests.
📄 Licen