A production-ready Node.js REST API boilerplate with built-in reliability using Temporal workflows, modern best practices, and complete deployment solutions for Docker and Kubernetes.
New! Check out our comprehensive documentation website with interactive guides, use cases, and deployment instructions.
- Temporal Workflows - Durable, reliable task execution with automatic retries
- Express.js 5 - Latest version with modern middleware
- PostgreSQL + Sequelize - Robust database with ORM and migrations
- OpenAPI 3.0 (Swagger) - Interactive API documentation
- Security First - Helmet, CORS, rate limiting, and best practices
- Winston Logging - Structured logging with daily rotation
- TypeScript - Full type safety with excellent IDE support
- Full Type Safety - Catch errors at compile time, not runtime
- Better IDE Support - IntelliSense, autocomplete, and inline documentation
- Easier Refactoring - Rename with confidence across the entire codebase
- Self-Documenting Code - Types serve as inline documentation
- Hot Reload in Dev - Development mode with instant TypeScript compilation
- Testing - Mocha + Chai + Sinon with comprehensive coverage
- Code Quality - ESLint v9 + Prettier + Husky hooks
- Modern JavaScript - ES Modules, async/await, latest Node features
- Docker - Multi-stage builds for API and Workers
- Kubernetes - Complete manifests with HPA, health checks
- Nginx - Production-grade reverse proxy configuration
- Monitoring - Health checks, readiness/liveness probes
- CI/CD Ready - GitHub Actions examples included
┌─────────────┐
│ Client │
└──────┬──────┘
│
┌──────▼──────┐
│ Nginx │ (Rate limiting, SSL, caching)
└──────┬──────┘
│
┌──────▼──────┐
│ API Server │ (Express.js - Handles HTTP requests)
└──────┬──────┘
│
├─────► PostgreSQL (Data persistence)
│
└─────► Temporal Server
▲
│
┌──────┴───────┐
│ Workers │ (Execute workflows/activities)
└──────────────┘
Why Temporal?
Traditional APIs lose work when services crash or restart. Temporal ensures your critical operations complete, even through failures:
- Automatic retries with exponential backoff
- Workflow state survives crashes and deployments
- Built-in monitoring and observability
- Easy to write complex, long-running processes
- Horizontal scaling of workers independent from API
Get up and running in under 5 minutes:
# 1. Clone the repository
git clone https://github.com/darshitvvora/node-temporal-postgres-boilerplate.git
cd node-temporal-postgres-boilerplate
# 2. Install dependencies
npm install
# 3. Set up environment
cp sample.env .env
# Edit .env with your database credentials
# 4. Create database and run migrations
createdb node_api_db
npm run migrate
# 5. Start Temporal Server (local development)
docker run -d -p 7233:7233 -p 8233:8233 temporalio/auto-setup:latest
OR
brew install temporal
temporal server start-dev
# 6. Start the application (3 terminals)
# Terminal 1: API Server (development mode with hot reload)
npm run dev
# Terminal 2: Temporal Worker (development mode with hot reload)
npm run start:worker:user:dev
# Terminal 3: Test the API
curl http://localhost:3015/healthDone! Your API is running at http://localhost:3015
- Swagger UI: http://localhost:3015/api-docs
- Temporal UI: http://localhost:8233
curl -X POST http://localhost:3015/api/users \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe",
"email": "john@example.com",
"mobile": "1234567890"
}'Watch the workflow execute in Temporal UI at http://localhost:8233 🎯
Comprehensive guides are available in the wiki/ folder:
| Guide | Description |
|---|---|
| Getting Started | Step-by-step setup and development guide |
| Temporal Workflows | Creating and managing Temporal workflows |
| API Documentation | OpenAPI/Swagger documentation standards |
| Deployment Guide | Docker, Kubernetes, and production deployment |
| Category | Technology | Version |
|---|---|---|
| Language | TypeScript | 5.x |
| Runtime | Node.js | >= 24.12.0 |
| Framework | Express.js | 5.x |
| Database | PostgreSQL | >= 14 |
| ORM | Sequelize | 6.x |
| Workflows | Temporal.io | 1.11+ |
| Logging | Winston | 3.x |
| Testing | Mocha + Chai + Sinon | Latest |
| Linting | ESLint (Flat Config) | 9.x |
| Formatting | Prettier | 3.x |
| Documentation | Swagger/OpenAPI | 3.0 |
| Security | Helmet | 8.x |
node-temporal-postgres-boilerplate/
├── src/ # TypeScript source files
│ ├── api/ # API resources
│ │ └── user/
│ │ ├── user.routes.ts # Route definitions
│ │ ├── user.controller.ts # Request handlers
│ │ ├── user.property.ts # Model schema
│ │ └── user.hookshot.ts # Event handlers
│ ├── config/ # Configuration
│ │ ├── environment/ # Environment configs
│ │ ├── express.ts # Express setup
│ │ ├── swagger.ts # API documentation config
│ │ ├── temporal.ts # Temporal client config
│ │ └── sequelize.cjs # Sequelize configuration (CommonJS)
│ ├── db/ # Database
│ │ ├── models/ # Sequelize models
│ │ └── migrations/ # Database migrations
│ ├── temporal/ # Temporal workflows
│ │ ├── activities/ # Business logic (DB, API calls)
│ │ ├── workflows/ # Workflow definitions
│ │ ├── clients/ # Workflow client functions
│ │ └── workers/ # Worker processes
│ ├── middleware/ # Express middleware
│ ├── types/ # TypeScript type definitions
│ ├── utils/ # Utility functions
│ ├── app.ts # Express app configuration
│ ├── routes.ts # Main router
│ └── server.ts # Application entry point
├── dist/ # Compiled JavaScript (production build)
├── tests/ # Test files
│ ├── integration/ # Integration tests
│ ├── setup.js # Test setup and configuration
│ └── global.js # Global test helpers
├── wiki/ # Detailed guides
├── logs/ # Application logs
├── docker-compose.yml # Docker Compose config
├── Dockerfile.api # API service Docker image
├── Dockerfile.worker # Worker service Docker image
├── k8s-deployment.yaml # Kubernetes manifests
├── nginx.sample.conf # Nginx configuration
├── .sequelizerc # Sequelize CLI configuration
├── tsconfig.json # TypeScript configuration
├── eslint.config.mjs # ESLint v9 flat configuration
└── package.json # Dependencies and scripts
# Development (with hot reload)
npm run dev # Start API in development mode (TypeScript)
npm run start:worker:user:dev # Start user worker in development mode
npm run debug # Start API in debug mode
# Production Build
npm run build # Compile TypeScript to JavaScript (→ dist/)
npm start # Start API from production build
npm run start:worker:user # Start user worker from production build
npm run start:worker:all # Start all workers from production build
# TypeScript
npm run typecheck # Type check without building
# Testing
npm test # Run all tests with coverage
# Code Quality
npm run lint # Lint code (max 0 warnings)
npm run lint:fix # Fix linting issues automatically
npm run pretty # Format code with Prettier
# Database
npm run migrate # Run database migrations
npm run clear-db # Drop and recreate database (⚠️ destructive)# Start all services (API, Worker, Nginx)
docker-compose up -d
# View logs
docker-compose logs -f
# Stop services
docker-compose downServices:
- API: http://localhost:3015 (direct) or http://localhost (via nginx)
- Swagger: http://localhost:3015/api-docs
- Nginx: http://localhost
# Build API image
docker build -f Dockerfile.api -t your-registry/node-api:v1.0.0 --target production .
# Build Worker image
docker build -f Dockerfile.worker -t your-registry/node-api-worker:v1.0.0 --target production .
# Push to registry
docker push your-registry/node-api:v1.0.0
docker push your-registry/node-api-worker:v1.0.0Complete Kubernetes manifests are included with:
- API Deployment with HPA (auto-scaling 3-10 replicas)
- Worker Deployment (2 replicas by default)
- Service, Ingress, ConfigMap, Secrets
- Health checks, resource limits, security policies
- NetworkPolicy, PodDisruptionBudget
# Create secrets
kubectl create secret generic node-api-secrets \
--from-literal=DB_PASSWORD=your-password \
--from-literal=DB_HOST=your-db-host \
--from-literal=TEMPORAL_ADDRESS=temporal.tmprl.cloud:7233
# Deploy
kubectl apply -f k8s-deployment.yaml
# Check status
kubectl get pods -l app=node-api
kubectl get ingress📘 See Deployment Guide for complete instructions
# Run all tests with coverage
npm test
# Run specific test file
NODE_ENV=test PORT=8000 npx mocha --exit --timeout 50000 --require ./tests/setup.js ./tests/integration/user.test.jsTest Coverage:
- Integration tests with real HTTP requests
- Mocked Temporal workflows using Sinon
- Database transaction rollback after tests
- Comprehensive assertions with Chai
- Coverage reporting via NYC (Istanbul)
Follow these steps to add a new resource (e.g., products):
# Create migration
npx sequelize-cli migration:generate --name create-products
# Define schema in migration file
# Run migration
npm run migratemkdir -p src/api/product
touch src/api/product/product.routes.js
touch src/api/product/product.controller.js
touch src/api/product/product.property.jsmkdir -p src/temporal/activities/product
mkdir -p src/temporal/workflows/product
touch src/temporal/activities/product/activities.js
touch src/temporal/workflows/product/createProduct.workflow.js
touch src/temporal/clients/product.client.jsAdd to src/routes.js:
import productRoutes from './api/product/product.routes.js';
app.use('/api/products', productRoutes);📘 See Getting Started Guide for detailed walkthrough
This boilerplate implements security best practices out of the box:
- Helmet - Security headers (XSS, clickjacking, etc.)
- CORS - Configurable cross-origin policies
- Rate Limiting - Nginx-level rate limiting (100 req/s)
- Input Validation - Schema validation for all inputs
- SQL Injection Prevention - Sequelize parameterized queries
- Non-root Docker User - Containers run as user
nodejs (1001) - Environment Variables - Secrets never committed to git
- HTTPS/TLS - Ready for SSL certificates
- Security Patches - Regular dependency updates
- Connection Pooling - Database connection pooling
- Compression - Gzip compression for responses
- Keep-Alive - HTTP keep-alive connections
- Caching Headers - Proper cache control
- Worker Scaling - Independent worker scaling
- Multi-stage Builds - Optimized Docker images
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes using conventional commits (
git cz) - Run tests (
npm test) - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development Guidelines:
- Follow the existing code style (ESLint + Prettier)
- Write tests for new features
- Update documentation as needed
- Use conventional commits
- Express.js 5 integration
- Temporal workflow engine integration
- PostgreSQL + Sequelize ORM
- OpenAPI 3.0 documentation
- Docker multi-stage builds
- Kubernetes manifests with HPA
- Nginx reverse proxy configuration
- Comprehensive testing setup
- ESLint v9 flat config
- Security best practices (Helmet, CORS)
- Full TypeScript migration with type safety
- Cron Schedule support with temporal
- Deployment guide on AWS EKS
- Deployment guide on GCP GKE
- Observability (Prometheus + Grafana) + Temporal observability
- Example of circuit breaker
- Example of outbox pattern
- Example of SAGA pattern
- Example of fan out pattern
- Example for scaling workers with K8s
- Example of fairness & priority within API
- Example of Nexus
- Sample UI in React
- Explore Monorepo structure
This project is licensed under the MIT License - see the LICENSE file for details.
- Express.js - Fast, unopinionated web framework
- Temporal.io - Durable execution platform
- Sequelize - Promise-based ORM
- @antfu/eslint-config - Modern ESLint config
- Angular Fullstack Generator - Inspiration for structure
- GitHub Issues: Report bugs or request features
- Discussions: Ask questions and share ideas
- Documentation: Check the
wiki/folder
Built with ❤️ by Darshit Vora
⭐ Star this repo if you find it helpful!
