A professional, universal, production-ready Node.js backend boilerplate built with Express, MongoDB, Redis, and comprehensive features to power any application (SaaS, e-commerce, blog, etc.).
- Features
- Prerequisites
- Installation
- Configuration
- Running the Application
- API Documentation
- Testing
- Database
- Deployment
- Project Structure
- Available Scripts
- Troubleshooting
- ✅ RESTful API with Express.js
- ✅ MongoDB database with Mongoose ODM
- ✅ Redis for caching and queues
- ✅ JWT Authentication with access & refresh tokens
- ✅ Role-based Access Control (RBAC)
- ✅ Input Validation with Joi
- ✅ ES Modules (import/export)
- 💳 Stripe Payment Integration with webhooks
- 🔔 Email Notifications (Nodemailer)
- 📱 Push Notifications (Firebase Cloud Messaging)
- 🛍️ Product Management with search & categories
- 📦 Order Management with status tracking
- 📄 Static Pages (Terms, Privacy, About)
- 📤 File Upload with Multer
- 🐳 Docker & Docker Compose support
- 🔄 Bull Queues for background jobs
- 📊 Prometheus Metrics endpoint
- 📝 Swagger/OpenAPI Documentation
- 📧 Automated Log Reports via email (daily, weekly, monthly, custom)
- 🧪 Jest testing with Supertest
- 🔍 ESLint & Prettier for code quality
- 🪝 Husky pre-commit hooks
- 🚀 GitHub Actions CI/CD pipeline (disabled by default for template)
- 🔒 Security best practices (Helmet, XSS, Rate limiting)
Before you begin, ensure you have the following installed on your system:
-
Node.js (>= 18.0.0)
- macOS:
brew install node@18
- Windows: Download from nodejs.org
- Linux (Ubuntu/Debian):
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - sudo apt-get install -y nodejs
- macOS:
-
npm (>= 9.0.0) - Comes with Node.js
node --version # Should be >= 18.0.0 npm --version # Should be >= 9.0.0
-
MongoDB (>= 5.0)
- macOS:
brew tap mongodb/brew brew install [email protected] brew services start [email protected]
- Windows: Download from mongodb.com
- Linux (Ubuntu/Debian):
wget -qO - https://www.mongodb.org/static/pgp/server-7.0.asc | sudo apt-key add - echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list sudo apt-get update sudo apt-get install -y mongodb-org sudo systemctl start mongod
- macOS:
-
Redis (>= 6.0) - Optional but recommended
- macOS:
brew install redis brew services start redis
- Windows: Download from redis.io or use Docker
- Linux (Ubuntu/Debian):
sudo apt-get update sudo apt-get install redis-server sudo systemctl start redis-server
- macOS:
-
Docker Desktop
- macOS/Windows: Download from docker.com
- Linux:
curl -fsSL https://get.docker.com -o get-docker.sh sh get-docker.sh sudo systemctl start docker
-
Docker Compose - Comes with Docker Desktop, or install separately:
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose
This is the easiest way to get started. Docker will handle MongoDB, Redis, and the application automatically.
-
Clone the repository
git clone https://github.com/devSahinur/nodejs-backend-boilerplate.git cd nodejs-backend-boilerplate -
Create environment file
cp .env.example .env
-
Edit
.envfile (optional - Docker works with defaults)# Use any text editor nano .env # OR vim .env # OR code .env
-
Start all services
npm run docker:up
This command will:
- Build the Docker image
- Start MongoDB on port 27017
- Start Redis on port 6379
- Start the API on port 3000
- Start Mongo Express (DB GUI) on port 8081
-
Verify services are running
docker-compose ps
-
Access the application
- API: http://localhost:3000
- Swagger Docs: http://localhost:3000/api-docs
- Health Check: http://localhost:3000/health
- Mongo Express: http://localhost:8081 (username:
admin, password:admin123)
-
View logs
docker-compose logs -f app
-
Stop services
npm run docker:down
If you prefer to run services locally without Docker:
-
Clone the repository
git clone https://github.com/devSahinur/nodejs-backend-boilerplate.git cd nodejs-backend-boilerplate -
Install dependencies
npm install
-
Ensure MongoDB is running
# macOS (if installed via Homebrew) brew services start mongodb-community # Linux sudo systemctl start mongod sudo systemctl status mongod # Windows - MongoDB should auto-start, or start manually from Services
-
Ensure Redis is running (optional but recommended)
# macOS brew services start redis # Linux sudo systemctl start redis-server sudo systemctl status redis-server # Windows - Use Docker or WSL
-
Create environment file
cp .env.example .env
-
Configure environment variables (see Configuration section)
-
Create logs directory
mkdir -p logs
-
Seed the database (optional - creates sample data)
npm run seed
This will create:
- Admin user:
[email protected]/Admin123! - Regular user:
[email protected]/User123! - Sample products
- Admin user:
-
Start the server
# Development mode (with hot reload) npm run dev # Production mode npm start
-
Verify the server is running
curl http://localhost:3000/health
Create a .env file in the root directory. Here's a detailed explanation of all variables:
# ===========================================
# SERVER CONFIGURATION
# ===========================================
NODE_ENV=development # Options: development, production, test
PORT=3000 # Port for the API server
BACKEND_IP=localhost # IP address to bind (use 0.0.0.0 for Docker)
# ===========================================
# DATABASE - MongoDB
# ===========================================
# Local MongoDB
MONGODB_URL=mongodb://localhost:27017/nodejs-backend
# Docker MongoDB (if using docker-compose)
# MONGODB_URL=mongodb://mongo:27017/nodejs-backend
# MongoDB Atlas (cloud)
# MONGODB_URL=mongodb+srv://username:[email protected]/dbname?retryWrites=true&w=majority
# ===========================================
# REDIS - For queues and caching
# ===========================================
REDIS_HOST=localhost # Use 'redis' if using Docker
REDIS_PORT=6379
REDIS_PASSWORD= # Leave empty if no password
# ===========================================
# JWT AUTHENTICATION
# ===========================================
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production-123456789
JWT_ACCESS_EXPIRATION_MINUTES=30 # Access token expiry (30 minutes)
JWT_REFRESH_EXPIRATION_DAYS=30 # Refresh token expiry (30 days)
JWT_RESET_PASSWORD_EXPIRATION_MINUTES=10
JWT_VERIFY_EMAIL_EXPIRATION_MINUTES=10
# ===========================================
# EMAIL - SMTP Configuration
# ===========================================
# Using Gmail (requires App Password)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
[email protected]
SMTP_PASSWORD=your-app-password # Generate at: https://myaccount.google.com/apppasswords
[email protected]
# Using SendGrid
# SMTP_HOST=smtp.sendgrid.net
# SMTP_PORT=587
# SMTP_USERNAME=apikey
# SMTP_PASSWORD=your-sendgrid-api-key
# Using Mailgun
# SMTP_HOST=smtp.mailgun.org
# SMTP_PORT=587
# [email protected]
# SMTP_PASSWORD=your-mailgun-password
# ===========================================
# STRIPE PAYMENTS
# ===========================================
# Get from: https://dashboard.stripe.com/test/apikeys
STRIPE_SECRET_KEY=sk_test_51234567890abcdefghijklmnopqrstuvwxyz
STRIPE_WEBHOOK_SECRET=whsec_1234567890abcdefghijklmnopqrstuvwxyz
# ===========================================
# FIREBASE CLOUD MESSAGING (Push Notifications)
# ===========================================
# Get from Firebase Console > Project Settings > Service Accounts
FIREBASE_PROJECT_ID=your-firebase-project-id
FIREBASE_CLIENT_EMAIL=firebase-adminsdk@your-project.iam.gserviceaccount.com
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nYour-Private-Key-Here\n-----END PRIVATE KEY-----\n"
# ===========================================
# AWS - Optional (for S3 file uploads)
# ===========================================
AWS_ACCESS_KEY_ID=your-aws-access-key
AWS_SECRET_ACCESS_KEY=your-aws-secret-key
AWS_REGION=us-east-1
S3_BUCKET_NAME=your-s3-bucket-name
# ===========================================
# CLIENT - Frontend URL (for email links)
# ===========================================
CLIENT_URL=http://localhost:3000 # Change to production URL in production-
Create account at stripe.com
-
Get test keys from Dashboard > API Keys
-
For webhooks:
# Install Stripe CLI brew install stripe/stripe-cli/stripe # Login stripe login # Forward webhooks to local server stripe listen --forward-to localhost:3000/api/v1/payments/webhook # Copy the webhook signing secret to .env as STRIPE_WEBHOOK_SECRET
- Go to Firebase Console
- Create a new project or select existing
- Go to Project Settings > Service Accounts
- Click Generate New Private Key
- Copy the values to
.env:FIREBASE_PROJECT_ID=your-project-id FIREBASE_CLIENT_EMAIL=firebase-adminsdk@your-project.iam.gserviceaccount.com FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
- Enable 2-Factor Authentication on your Google Account
- Go to App Passwords
- Create app password for "Mail"
- Use the generated password in
.env:[email protected] SMTP_PASSWORD=generated-app-password
# With hot reload (recommended for development)
npm run devThe server will automatically restart when you make changes to the code.
# Start the server
npm start# Install PM2 globally
npm install -g pm2
# Start with PM2
pm2 start src/index.js --name nodejs-backend
# View logs
pm2 logs nodejs-backend
# Restart
pm2 restart nodejs-backend
# Stop
pm2 stop nodejs-backend
# Monitor
pm2 monitOnce the server is running, you can access:
- URL: http://localhost:3000/api-docs
- Features:
- Try out API endpoints directly
- View request/response schemas
- See authentication requirements
-
Health Check: http://localhost:3000/health
{ "status": "OK", "timestamp": "2025-01-02T10:30:00.000Z", "uptime": 123.456, "environment": "development" } -
Prometheus Metrics: http://localhost:3000/metrics
- HTTP request metrics
- Database query performance
- Background job statistics
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /api/v1/auth/register |
Register new user | No |
| POST | /api/v1/auth/login |
Login user | No |
| POST | /api/v1/auth/logout |
Logout user | Yes |
| POST | /api/v1/auth/refresh-tokens |
Refresh auth tokens | No |
| POST | /api/v1/auth/forgot-password |
Send password reset email | No |
| POST | /api/v1/auth/reset-password |
Reset password | No |
| POST | /api/v1/auth/send-verification-email |
Send verification email | Yes |
| POST | /api/v1/auth/verify-email |
Verify email | No |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /api/v1/users |
Create user | Admin |
| GET | /api/v1/users |
Get all users | Admin |
| GET | /api/v1/users/:userId |
Get user | Yes |
| PATCH | /api/v1/users/:userId |
Update user | Yes |
| DELETE | /api/v1/users/:userId |
Delete user | Yes |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /api/v1/products |
Create product | Admin |
| GET | /api/v1/products |
Get all products | No |
| GET | /api/v1/products/:productId |
Get product | No |
| GET | /api/v1/products/slug/:slug |
Get product by slug | No |
| GET | /api/v1/products/search?q=query |
Search products | No |
| GET | /api/v1/products/featured |
Get featured products | No |
| GET | /api/v1/products/category/:category |
Get products by category | No |
| PATCH | /api/v1/products/:productId |
Update product | Admin |
| DELETE | /api/v1/products/:productId |
Delete product | Admin |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /api/v1/orders |
Create order | Yes |
| GET | /api/v1/orders |
Get all orders | Admin |
| GET | /api/v1/orders/my-orders |
Get user's orders | Yes |
| GET | /api/v1/orders/:orderId |
Get order | Yes |
| GET | /api/v1/orders/status/:status |
Get orders by status | Admin |
| PATCH | /api/v1/orders/:orderId/status |
Update order status | Admin |
| POST | /api/v1/orders/:orderId/cancel |
Cancel order | Yes |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /api/v1/payments/create-intent |
Create payment intent | Yes |
| GET | /api/v1/payments/:paymentIntentId |
Get payment details | Yes |
| POST | /api/v1/payments/:paymentIntentId/refund |
Create refund | Admin |
| POST | /api/v1/payments/webhook |
Stripe webhook | No |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /api/v1/notifications/email |
Send email | Admin |
| POST | /api/v1/notifications/push |
Send push notification | Admin |
| POST | /api/v1/notifications/push/multicast |
Send to multiple devices | Admin |
| POST | /api/v1/notifications/push/topic |
Send to topic | Admin |
| POST | /api/v1/notifications/topic/subscribe |
Subscribe to topic | Yes |
| POST | /api/v1/notifications/topic/unsubscribe |
Unsubscribe from topic | Yes |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /api/v1/static/terms |
Get terms of service | No |
| GET | /api/v1/static/privacy |
Get privacy policy | No |
| GET | /api/v1/static/about |
Get about page | No |
npm testnpm run test:watchnpm test -- --coverage# After running tests with coverage
open coverage/lcov-report/index.htmlTests are located in the tests/ directory:
tests/
├── integration/ # Integration tests
│ ├── auth.test.js
│ ├── user.test.js
│ └── product.test.js
└── unit/ # Unit tests
├── services/
└── utils/
Example test:
import request from 'supertest';
import app from '../src/app.js';
describe('Auth endpoints', () => {
test('should register a new user', async () => {
const res = await request(app)
.post('/api/v1/auth/register')
.send({
fullName: 'Test User',
email: '[email protected]',
password: 'Password123!',
})
.expect(201);
expect(res.body.user).toHaveProperty('id');
expect(res.body.tokens).toHaveProperty('access');
});
});# Create a new migration
npm run migrate:create -- add-user-preferences
# Run pending migrations
npm run migrate:up
# Rollback last migration
npm run migrate:downPopulate the database with sample data:
npm run seedThis creates:
-
Admin User:
- Email:
[email protected] - Password:
Admin123!
- Email:
-
Regular Users:
- Email:
[email protected], Password:User123! - Email:
[email protected], Password:User123!
- Email:
-
Sample Products: 5 electronics products
# Start Docker services
npm run docker:up
# Access Mongo Express
open http://localhost:8081- Username:
admin - Password:
admin123
- Download MongoDB Compass
- Connect with:
mongodb://localhost:27017
# Check for linting errors
npm run lint
# Fix linting errors automatically
npm run lint -- --fix# Format all files
npm run format
# Check formatting without writing
npm run format -- --checkHusky runs linting and formatting automatically before commits:
git add .
git commit -m "feat: add new feature"
# Husky will run lint and format automaticallyThe boilerplate includes a powerful automated log reporting system that sends email summaries of your application logs on a configurable schedule.
- 📧 Email Reports: Receive beautifully formatted HTML email reports
- ⏰ Flexible Scheduling: Daily, weekly, monthly, or custom schedules
- 📊 Comprehensive Stats: Error counts, warnings, system metrics
- 🎨 Visual Dashboard: Color-coded health status and statistics
- 🔍 Error Details: Top errors and warnings with timestamps
- 💻 System Metrics: Memory usage, uptime, Node.js version
- 🌍 Timezone Support: Configure reports in any timezone
- 👥 Multiple Recipients: Send to multiple email addresses
Add these settings to your .env file:
# Enable or disable automatic log reports
LOG_REPORT_ENABLED=true
# Frequency: daily, weekly, biweekly, monthly, every3days, every7days
LOG_REPORT_FREQUENCY=weekly
# Number of days to include in the report
LOG_REPORT_DAYS=7
# Comma-separated list of email recipients
[email protected],[email protected]
# Timezone (e.g., UTC, America/New_York, Asia/Dhaka, Europe/London)
LOG_REPORT_TIMEZONE=UTC| Frequency | Description | Report Days |
|---|---|---|
daily |
Every day at 9:00 AM | 1 |
weekly |
Every Monday at 9:00 AM | 7 |
biweekly |
Every 2 weeks on Monday at 9:00 AM | 14 |
monthly |
First day of each month at 9:00 AM | 30 |
every3days |
Every 3 days at 9:00 AM | 3 |
every7days |
Every 7 days at 9:00 AM | 7 |
hourly |
Every hour (for testing) | 1 |
every10min |
Every 10 minutes (for testing) | 1 |
Each report includes:
- Health Status Badge: Visual indicator (HEALTHY, ATTENTION, WARNING, CRITICAL)
- Statistics Grid:
- Total log entries
- Error count
- Warning count
- Error rate percentage
- Recent Errors: Top 10 most recent errors with stack traces
- Recent Warnings: Top 10 warnings
- System Metrics:
- Application uptime
- Memory usage (RSS, Heap)
- Node.js version
- Platform information
- Log Distribution: Breakdown by log level (info, http, debug)
| Status | Error Count | Color |
|---|---|---|
| HEALTHY | 0-10 errors | Green |
| ATTENTION | 11-50 errors | Yellow |
| WARNING | 51-100 errors | Orange |
| CRITICAL | 100+ errors | Red |
You can manually trigger a log report without waiting for the schedule:
import { sendImmediateReport } from './src/config/scheduler.js';
// Send to configured recipients
await sendImmediateReport();
// Send to custom recipients with custom days
await sendImmediateReport(['[email protected]'], 30);To change when reports are sent, modify the schedule in src/config/scheduler.js:
const SCHEDULE_PATTERNS = {
daily: '0 9 * * *', // 9:00 AM every day
weekly: '0 9 * * 1', // 9:00 AM every Monday
// Cron format: minute hour day month day-of-week
};Cron format examples:
0 9 * * *- Daily at 9:00 AM0 0 * * 0- Weekly on Sunday at midnight0 18 * * 5- Weekly on Friday at 6:00 PM0 8 1 * *- Monthly on the 1st at 8:00 AM
Set LOG_REPORT_ENABLED=false in your .env file or comment out the startLogReportScheduler() call in src/index.js.
For testing purposes, use shorter intervals:
LOG_REPORT_ENABLED=true
LOG_REPORT_FREQUENCY=every10min
LOG_REPORT_DAYS=1
[email protected]Then check your email after 10 minutes to verify the report format.
No emails received?
- Check SMTP configuration in
.env - Verify
LOG_REPORT_ENABLED=true - Ensure recipients are configured correctly
- Check application logs for scheduler errors
- For Gmail, use an App Password
Want different report formats?
- Modify
src/services/emailReport.service.js - Customize HTML template in
generateEmailTemplate() - Add custom metrics in
src/services/logReport.service.js
- AWS Account
- AWS CLI installed
- Docker installed
-
Configure AWS CLI
aws configure
-
Create ECR Repository
aws ecr create-repository --repository-name nodejs-backend-boilerplate
-
Configure GitHub Secrets
Go to your GitHub repository → Settings → Secrets and add:
AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY
-
Push to main branch
git push origin main
The CI/CD workflow is disabled by default for the template. To enable it:
# Rename the workflow file to enable it
mv .github/workflows/ci-cd.yml.disabled .github/workflows/ci-cd.ymlThe GitHub Actions workflow will:
- Run tests
- Build Docker image
- Push to Amazon ECR
- Deploy to AWS ECS
Note: Make sure to configure GitHub Secrets for AWS credentials:
AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYCODECOV_TOKEN(optional)
# Install Heroku CLI
brew install heroku
# Login
heroku login
# Create app
heroku create your-app-name
# Add MongoDB addon
heroku addons:create mongolab
# Add Redis addon
heroku addons:create heroku-redis
# Set environment variables
heroku config:set NODE_ENV=production
heroku config:set JWT_SECRET=your-secret-key
# Deploy
git push heroku main- Go to DigitalOcean App Platform
- Click "Create App"
- Connect your GitHub repository
- Configure build settings:
- Build Command:
npm install - Run Command:
npm start
- Build Command:
- Add MongoDB and Redis databases
- Set environment variables
- Deploy
# SSH into your server
ssh user@your-server-ip
# Install Node.js
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
# Install MongoDB
# (see Prerequisites section)
# Install PM2
npm install -g pm2
# Clone repository
git clone your-repo-url
cd your-repo
# Install dependencies
npm install
# Set up environment variables
nano .env
# Start with PM2
pm2 start src/index.js --name nodejs-backend
# Set up PM2 to start on boot
pm2 startup
pm2 save
# Set up Nginx as reverse proxy
sudo apt install nginx
sudo nano /etc/nginx/sites-available/defaultNginx config:
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}# Restart Nginx
sudo systemctl restart nginxnodejs-backend-boilerplate/
├── .github/
│ └── workflows/
│ └── ci-cd.yml # GitHub Actions CI/CD pipeline
├── .husky/
│ ├── commit-msg # Commitlint hook
│ └── pre-commit # Lint & format hook
├── docker/
│ ├── Dockerfile # Docker image definition
│ └── docker-compose.yml # Multi-container setup
├── logs/ # Application logs (gitignored)
├── migrations/ # Database migrations
├── public/ # Static files
├── scripts/
│ └── seed.js # Database seeding script
├── src/
│ ├── config/ # Configuration files
│ │ ├── config.js # Environment configuration
│ │ ├── database.js # MongoDB connection
│ │ ├── logger.js # Winston logger setup
│ │ ├── metrics.js # Prometheus metrics
│ │ ├── morgan.js # HTTP request logger
│ │ ├── passport.js # Passport JWT strategy
│ │ ├── redis.js # Redis client
│ │ ├── roles.js # User roles definition
│ │ ├── swagger.js # Swagger/OpenAPI setup
│ │ └── tokens.js # Token types
│ ├── controllers/ # Request handlers
│ │ ├── auth.controller.js
│ │ ├── user.controller.js
│ │ ├── product.controller.js
│ │ ├── order.controller.js
│ │ ├── payment.controller.js
│ │ └── notification.controller.js
│ ├── middlewares/ # Custom middleware
│ │ ├── auth.js # JWT authentication
│ │ ├── error.js # Error handling
│ │ ├── validate.js # Request validation
│ │ ├── rateLimiter.js # Rate limiting
│ │ └── fileUpload.js # File upload handling
│ ├── models/ # Mongoose models
│ │ ├── user.model.js
│ │ ├── token.model.js
│ │ ├── product.model.js
│ │ ├── order.model.js
│ │ ├── terms.model.js
│ │ ├── privacy.model.js
│ │ ├── about.model.js
│ │ └── plugins/ # Mongoose plugins
│ │ ├── paginate.plugin.js
│ │ └── toJSON.plugin.js
│ ├── queues/ # Background job queues
│ │ ├── index.js # Queue definitions
│ │ └── processors/ # Job processors
│ │ ├── email.processor.js
│ │ ├── notification.processor.js
│ │ └── order.processor.js
│ ├── routes/ # API routes
│ │ └── v1/
│ │ ├── index.js # Route aggregator
│ │ ├── auth.routes.js
│ │ ├── user.routes.js
│ │ ├── product.routes.js
│ │ ├── order.routes.js
│ │ ├── payment.routes.js
│ │ ├── notification.routes.js
│ │ ├── terms.routes.js
│ │ ├── privacy.routes.js
│ │ └── about.routes.js
│ ├── services/ # Business logic
│ │ ├── auth.service.js
│ │ ├── user.service.js
│ │ ├── token.service.js
│ │ ├── product.service.js
│ │ ├── order.service.js
│ │ ├── payments/
│ │ │ └── stripe.service.js
│ │ └── notifications/
│ │ ├── email.service.js
│ │ └── fcm.service.js
│ ├── utils/ # Utility functions
│ │ ├── ApiError.js # Custom error class
│ │ ├── catchAsync.js # Async error wrapper
│ │ └── pick.js # Object property picker
│ ├── validations/ # Joi validation schemas
│ │ ├── auth.validation.js
│ │ ├── user.validation.js
│ │ ├── product.validation.js
│ │ ├── order.validation.js
│ │ └── custom.validation.js
│ ├── app.js # Express app setup
│ └── index.js # Entry point
├── tests/ # Test files
│ ├── integration/
│ │ └── auth.test.js
│ └── unit/
├── .dockerignore # Docker ignore file
├── .env.example # Environment variables template
├── .eslintrc.json # ESLint configuration
├── .gitignore # Git ignore file
├── .prettierrc.json # Prettier configuration
├── commitlint.config.js # Commitlint configuration
├── jest.config.js # Jest configuration
├── migrate-mongo-config.js # Migration configuration
├── package.json # NPM dependencies
└── README.md # This file
This boilerplate includes a comprehensive set of npm scripts to streamline your development workflow. Below is a detailed explanation of each script:
Description: Starts the development server with automatic hot-reload using Nodemon.
When to use: During active development when you want the server to automatically restart on file changes.
Example:
npm run devOutput: Server starts on http://localhost:3000 with auto-reload enabled.
Description: Starts the production server without hot-reload.
When to use: In production environments or when you want to test the production build locally.
Example:
NODE_ENV=production npm startNote: Ensure all environment variables are set before running in production.
Description: Runs all test suites with coverage reporting using Jest.
When to use: Before committing code, in CI/CD pipelines, or when you want to verify all tests pass.
Example:
npm testWhat it does:
- Runs all
*.test.jsand*.spec.jsfiles - Generates coverage reports in
coverage/directory - Requires 70% code coverage (configurable in
jest.config.js)
View coverage report:
open coverage/lcov-report/index.html # macOS
xdg-open coverage/lcov-report/index.html # LinuxDescription: Runs tests in watch mode, re-running tests when files change.
When to use: During test-driven development (TDD) or when actively writing tests.
Example:
npm run test:watchFeatures:
- Automatically re-runs tests on file changes
- Interactive mode with options to filter tests
- Press
pto filter by filename pattern - Press
tto filter by test name pattern
Description: Checks and automatically fixes code style issues using ESLint.
When to use: Before committing code or when you want to enforce coding standards.
Example:
npm run lintWhat it checks:
- Airbnb JavaScript style guide compliance
- Import/export statement correctness
- Potential bugs and code smells
- Best practices for Node.js and Express
Configuration: See .eslintrc.json for rules.
Description: Formats all code files according to Prettier configuration.
When to use: Before committing code to ensure consistent formatting across the codebase.
Example:
npm run formatWhat it formats:
- JavaScript/JSON files
- Markdown documentation
- YAML configuration files
Check without formatting:
npm run format -- --checkConfiguration: See .prettierrc for formatting rules.
Description: Starts all Docker containers in detached mode (app, MongoDB, Redis).
When to use: When you want to run the entire stack using Docker without installing MongoDB and Redis locally.
Example:
npm run docker:upWhat it starts:
- Application container on port 3000
- MongoDB container on port 27017
- Redis container on port 6379
- Mongo Express (DB admin UI) on port 8081
Access services:
- API: http://localhost:3000
- Mongo Express: http://localhost:8081 (admin/pass)
Description: Stops and removes all Docker containers.
When to use: When you're done with Docker development and want to free up resources.
Example:
npm run docker:downRemove volumes too:
npm run docker:down -- -vDescription: Rebuilds Docker images from scratch.
When to use: After changing Dockerfile, package.json dependencies, or when images are corrupted.
Example:
npm run docker:buildForce rebuild without cache:
npm run docker:build -- --no-cacheDescription: Populates the database with sample data for development.
When to use: After initial setup or when you need fresh test data.
Example:
npm run seedWhat it creates:
- Admin user ([email protected] / Admin123!)
- Sample products with categories
- Sample orders
Note: Clears existing data before seeding. Use with caution in production.
Description: Runs pending database migrations.
When to use: After pulling new code with database schema changes or when deploying to production.
Example:
npm run migrate:upConfiguration: See migrate-mongo-config.js and migrations/ directory.
Description: Rolls back the last applied migration.
When to use: When you need to undo the most recent database migration.
Example:
npm run migrate:downWarning: This may result in data loss. Always backup your database first.
Description: Creates a new migration file.
When to use: When you need to make database schema changes.
Example:
npm run migrate:create add_user_rolesOutput: Creates a new file in migrations/ directory with timestamp.
Description: Installs Husky git hooks for pre-commit validation.
When to use: Automatically runs after npm install. Manually run if hooks aren't working.
Example:
npm run prepareWhat it sets up:
- Pre-commit hook: Runs linting and formatting on staged files
- Commit-msg hook: Validates commit message format (Conventional Commits)
Bypass hooks (not recommended):
git commit --no-verify -m "message"| Script | Use Case | Required Services |
|---|---|---|
npm run dev |
Local development | MongoDB, Redis |
npm start |
Production run | MongoDB, Redis |
npm test |
Testing & CI/CD | MongoDB, Redis |
npm run test:watch |
TDD workflow | MongoDB, Redis |
npm run lint |
Code quality check | None |
npm run format |
Code formatting | None |
npm run docker:up |
Docker development | Docker |
npm run docker:down |
Stop Docker | Docker |
npm run docker:build |
Rebuild images | Docker |
npm run seed |
Generate test data | MongoDB |
npm run migrate:up |
Apply migrations | MongoDB |
npm run migrate:down |
Revert migration | MongoDB |
npm run migrate:create |
Create migration | None |
npm run prepare |
Setup git hooks | None |
Starting development for the first time:
npm install
cp .env.example .env # Configure your environment
npm run migrate:up # Apply database migrations
npm run seed # Add sample data
npm run dev # Start developingBefore committing code:
npm run lint # Fix code style issues
npm run format # Format all files
npm test # Ensure tests pass
git add .
git commit -m "feat: your feature" # Husky hooks run automaticallyUsing Docker:
npm run docker:build # First time only
npm run docker:up # Start all services
# Develop...
npm run docker:down # When finishedDeploying to production:
npm run lint
npm test
npm run migrate:up # On production server
NODE_ENV=production npm start# Find process using port 3000
lsof -i :3000
# Kill the process
kill -9 <PID>
# Or change port in .env
PORT=3001# Check if MongoDB is running
# macOS
brew services list | grep mongodb
# Linux
sudo systemctl status mongod
# Start MongoDB
brew services start mongodb-community # macOS
sudo systemctl start mongod # Linux# Check if Redis is running
redis-cli ping # Should return "PONG"
# Start Redis
brew services start redis # macOS
sudo systemctl start redis-server # Linux# Clear node_modules and reinstall
rm -rf node_modules package-lock.json
npm install# Fix npm permissions (macOS/Linux)
sudo chown -R $USER:$GROUP ~/.npm
sudo chown -R $USER:$GROUP ~/.config# Remove all containers and volumes
docker-compose down -v
# Rebuild from scratch
docker-compose build --no-cache
docker-compose up -d# Reinstall Husky
npm uninstall husky
npm install husky --save-dev
npm run prepare- Check SMTP credentials in
.env - For Gmail, ensure you're using an App Password (not your account password)
- Check firewall/antivirus settings
- Test SMTP connection:
telnet smtp.gmail.com 587
# Ensure Stripe CLI is running
stripe listen --forward-to localhost:3000/api/v1/payments/webhook
# Check webhook secret matches .env
stripe listenEnsure all import statements include .js extension:
// ✅ Correct
import User from './models/user.model.js';
// ❌ Wrong
import User from './models/user.model';- ✅ Passwords hashed with bcrypt (8 rounds)
- ✅ JWT tokens for stateless authentication
- ✅ Rate limiting on auth endpoints (5 requests per minute)
- ✅ Input validation with Joi
- ✅ XSS protection with xss-clean
- ✅ NoSQL injection prevention with express-mongo-sanitize
- ✅ Security headers with Helmet
- ✅ CORS enabled with configurable origins
- ✅ Environment variables for sensitive data
- ✅ HTTPS recommended for production
- ⚡ Redis caching for frequently accessed data
- ⚡ Bull queues for background job processing
- ⚡ Database indexing on frequently queried fields
- ⚡ Gzip compression for API responses
- ⚡ Prometheus metrics for monitoring
- ⚡ Connection pooling for MongoDB
- ⚡ Optimized Docker multi-stage builds
We welcome contributions! Please follow these steps:
- Fork the repository
- Create your feature branch
git checkout -b feature/amazing-feature
- Make your changes
- Run tests and linting
npm test npm run lint - Commit your changes (follows conventional commits)
git commit -m "feat: add amazing feature" - Push to the branch
git push origin feature/amazing-feature
- Open a Pull Request
We use Conventional Commits:
feat:New featurefix:Bug fixdocs:Documentation onlystyle:Code style changes (formatting)refactor:Code refactoringperf:Performance improvementstest:Adding testschore:Maintenance tasks
This project is licensed under the MIT License.
- 📧 Email: [email protected]
- 💬 Discord: Join our server
- 🐛 Issues: GitHub Issues
- 📚 Docs: Full Documentation
- Express.js - Web framework
- Mongoose - MongoDB ODM
- Passport.js - Authentication
- Stripe - Payment processing
- Firebase - Push notifications
- Bull - Queue processing
- Jest - Testing framework
Built with ❤️ for developers by developers
Need help? Open an issue or check our FAQ