Skip to content

eldhopaulose/TS-BoilerplateX

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

TypeScript Express 5 Node.js Pino Zod ESLint

TS-BoilerplateX

πŸš€ A production-ready, batteries-included TypeScript + Express.js boilerplate with modern tooling, structured logging, request validation, rate limiting, and more.

TS-BoilerplateX gives developers a robust starting point for building powerful REST APIs and web applications. It combines TypeScript's static typing with Express.js 5's flexibility, pre-configured with industry best practices for security, observability, and developer experience.


✨ Features

Category Feature Details
πŸ—οΈ Core Express.js 5 Latest version with improved routing & async error handling
πŸ“ Language TypeScript 5.9+ Strict mode, ES2022 target, full type safety
πŸ”’ Security Helmet Sets secure HTTP headers automatically
πŸ”’ Security CORS Configurable cross-origin resource sharing
πŸ”’ Security Rate Limiting Two-tier: global + strict (for auth endpoints)
πŸ“Š Logging Pino Structured JSON logging (prod) / pretty print (dev)
πŸ†” Tracing Request ID UUID-based request tracking via X-Request-Id header
βœ… Validation Zod v4 Schema-based request validation middleware
πŸ’š Health Health Check /api/health endpoint with uptime & memory stats
πŸ›‘οΈ Resilience Graceful Shutdown Clean SIGTERM/SIGINT handling with connection draining
πŸ›‘οΈ Resilience Error Handling Global error handler + uncaught exception/rejection capture
🧹 Linting ESLint 10 Flat config with typescript-eslint
πŸ“¦ Bundling esbuild Lightning-fast production builds
πŸ“– Docs TypeDoc Auto-generated API documentation
πŸ”„ DX Nodemon Hot-reload during development

πŸ“‹ Prerequisites

  • Node.js >= 18.0.0
  • npm >= 9.0.0

πŸš€ Quick Start

Using npx (Recommended)

npx ts-boilerplatex

Manual Installation

# Clone the repository
git clone https://github.com/eldhopaulose/TS-BoilerplateX.git
cd TS-BoilerplateX

# Install dependencies
npm install

# Copy environment variables
cp .env.example .env

# Start development server
npm run dev

The server will start at http://localhost:3000 with hot-reload enabled.


βš™οΈ Environment Variables

Variable Default Description
PORT 3000 Server port
NODE_ENV development Environment (development / production)
LOG_LEVEL debug (dev) / info (prod) Pino log level
RATE_LIMIT_WINDOW_MS 900000 Rate limit window (ms) β€” 15 min
RATE_LIMIT_MAX 100 Max requests per window (global)
STRICT_RATE_LIMIT_WINDOW_MS 900000 Strict rate limit window (ms)
STRICT_RATE_LIMIT_MAX 10 Max requests per window (strict)

πŸ“‚ Project Structure

TS-BoilerplateX/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ bin/
β”‚   β”‚   └── server.ts              # HTTP server creation & lifecycle
β”‚   β”œβ”€β”€ controller/
β”‚   β”‚   β”œβ”€β”€ indexController.ts     # Root route handler (API index)
β”‚   β”‚   └── userController.ts      # User CRUD handlers with logging
β”‚   β”œβ”€β”€ middleware/
β”‚   β”‚   β”œβ”€β”€ index.ts               # Barrel export for all middleware
β”‚   β”‚   β”œβ”€β”€ rateLimiter.ts         # Global & strict rate limiters
β”‚   β”‚   β”œβ”€β”€ requestId.ts           # UUID-based request ID tracking
β”‚   β”‚   └── validate.ts            # Zod schema validation middleware
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   └── user.model.ts          # User data model (in-memory store)
β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   β”œβ”€β”€ health.ts              # Health check endpoint
β”‚   β”‚   β”œβ”€β”€ index.ts               # Root routes
β”‚   β”‚   └── user.routes.ts         # User CRUD routes with validation
β”‚   β”œβ”€β”€ schemas/
β”‚   β”‚   └── user.schema.ts         # Zod validation schemas for User API
β”‚   β”œβ”€β”€ types/
β”‚   β”‚   └── express.d.ts           # Express type augmentations
β”‚   β”œβ”€β”€ utils/
β”‚   β”‚   └── logger.ts              # Pino logger configuration
β”‚   └── main.ts                    # Application entry point
β”œβ”€β”€ .env.example                   # Environment variable template
β”œβ”€β”€ eslint.config.mjs              # ESLint 10 flat config
β”œβ”€β”€ nodemon.json                   # Development server config
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json                  # TypeScript compiler config
└── README.md

πŸ“œ Available Scripts

Script Description
npm run dev Start dev server with nodemon (hot-reload)
npm run start Start with ts-node (no compilation needed)
npm run production Run compiled JS from dist/
npm run build Compile TypeScript to JavaScript
npm run build-all Clean, compile, and bundle with esbuild
npm run lint Run ESLint on source files
npm run lint:fix Run ESLint with auto-fix
npm run test Run tests with Jest
npm run docs Generate API docs with TypeDoc
npm run clean Remove build artifacts

🎯 Example API β€” User CRUD

The boilerplate ships with a fully working User CRUD API that demonstrates all features. Start the server and try:

πŸ“ Endpoints

Method Endpoint Description Features Used
GET / API index (lists all routes) β€”
GET /api/health Health check Memory stats, uptime
GET /api/users List all users (paginated) Zod query validation
GET /api/users/stats User statistics Aggregation
GET /api/users/:id Get user by ID Zod UUID validation
POST /api/users Create a user Zod body validation, strict rate limit
PUT /api/users/:id Update a user Zod partial validation
DELETE /api/users/:id Delete a user Strict rate limit

πŸ§ͺ Try it with cURL

1. List all users (with pagination & filtering):

curl http://localhost:3000/api/users?page=1&limit=10

# Filter by role
curl http://localhost:3000/api/users?role=admin

# Filter by active status
curl http://localhost:3000/api/users?isActive=true

Response:

{
  "success": true,
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Eldho Paulose",
      "email": "eldho@example.com",
      "age": 28,
      "role": "admin",
      "isActive": true,
      "createdAt": "2026-03-27T12:00:00.000Z",
      "updatedAt": "2026-03-27T12:00:00.000Z"
    }
  ],
  "pagination": {
    "total": 3,
    "page": 1,
    "limit": 10,
    "totalPages": 1,
    "hasNextPage": false,
    "hasPrevPage": false
  }
}

2. Create a new user:

curl -X POST http://localhost:3000/api/users \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Alice Johnson",
    "email": "alice@example.com",
    "age": 30,
    "role": "moderator"
  }'

Response (201):

{
  "success": true,
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "Alice Johnson",
    "email": "alice@example.com",
    "age": 30,
    "role": "moderator",
    "isActive": true,
    "createdAt": "2026-03-27T12:01:00.000Z",
    "updatedAt": "2026-03-27T12:01:00.000Z"
  }
}

3. Validation error example (missing required fields):

curl -X POST http://localhost:3000/api/users \
  -H "Content-Type: application/json" \
  -d '{"name": "A"}'

Response (422):

{
  "error": "Validation Error",
  "details": [
    { "field": "body.name", "message": "Name must be at least 2 characters" },
    { "field": "body.email", "message": "Required" },
    { "field": "body.age", "message": "Required" }
  ]
}

4. Update a user:

curl -X PUT http://localhost:3000/api/users/<user-id> \
  -H "Content-Type: application/json" \
  -d '{"name": "Alice Smith", "age": 31}'

5. Delete a user:

curl -X DELETE http://localhost:3000/api/users/<user-id>

6. Get user statistics:

curl http://localhost:3000/api/users/stats

Response:

{
  "success": true,
  "data": {
    "total": 3,
    "active": 2,
    "inactive": 1,
    "byRole": { "admin": 1, "user": 1, "moderator": 1 },
    "averageAge": 28
  }
}

7. Health check:

curl http://localhost:3000/api/health

πŸ”§ Advanced Features

πŸ“Š Structured Logging (Pino)

Pino provides ultra-fast, structured JSON logging in production and colorful, readable output in development.

import logger from "./utils/logger";

logger.info("Server started");
logger.error({ err: error }, "Database connection failed");
logger.debug({ userId: 123 }, "User fetched");

Development output:

[12:34:56] INFO: Incoming request
    method: "GET"
    url: "/api/health"
    requestId: "550e8400-e29b-41d4-a716-446655440000"

Production output (JSON):

{"level":"info","time":"2026-03-27T12:34:56.789Z","method":"GET","url":"/api/health","requestId":"550e8400-e29b-41d4-a716-446655440000","msg":"Incoming request"}

βœ… Request Validation (Zod v4)

Type-safe request validation using Zod schemas:

import { z } from "zod";
import { validate } from "../middleware/validate";

const createUserSchema = z.object({
  body: z.object({
    name: z.string().min(1, "Name is required"),
    email: z.string().email("Invalid email address"),
    age: z.number().int().min(18, "Must be at least 18"),
  }),
});

router.post("/users", validate(createUserSchema), userController.create);

Validation error response (422):

{
  "error": "Validation Error",
  "details": [
    { "field": "body.email", "message": "Invalid email address" },
    { "field": "body.age", "message": "Must be at least 18" }
  ]
}

πŸ”’ Rate Limiting

Two-tier rate limiting out of the box:

import { globalRateLimiter, strictRateLimiter } from "../middleware";

// Global: applied to all routes (100 req/15min by default)
app.use(globalRateLimiter);

// Strict: for sensitive endpoints (10 req/15min by default)
router.post("/auth/login", strictRateLimiter, authController.login);

πŸ†” Request ID Tracking

Every request gets a unique UUID via the X-Request-Id header. Pass an existing ID from upstream services, or one will be auto-generated:

# Auto-generated
curl http://localhost:3000/
# Response header: X-Request-Id: 550e8400-e29b-41d4-a716-446655440000

# Pass your own
curl -H "X-Request-Id: my-trace-id" http://localhost:3000/
# Response header: X-Request-Id: my-trace-id

πŸ’š Health Check

Built-in health check endpoint for load balancers and container orchestration:

curl http://localhost:3000/api/health
{
  "status": "ok",
  "uptime": 123.456,
  "timestamp": "2026-03-27T12:34:56.789Z",
  "memoryUsage": {
    "rss": "45.23 MB",
    "heapUsed": "22.11 MB",
    "heapTotal": "35.50 MB"
  },
  "environment": "development"
}

πŸ›‘οΈ Graceful Shutdown

The server handles SIGTERM and SIGINT signals gracefully, allowing in-flight requests to complete before shutting down (with a 10-second timeout):

// Automatically handled β€” no configuration needed
// Logs: "Received SIGTERM. Shutting down gracefully..."
// Logs: "HTTP server closed."

πŸ”Œ Middleware Stack

The following middleware is applied in order:

  1. Helmet β€” Sets secure HTTP headers (XSS protection, CSP, etc.)
  2. CORS β€” Enables cross-origin requests
  3. Rate Limiter β€” Prevents abuse with configurable limits
  4. Request ID β€” Assigns unique trace IDs to each request
  5. Pino Logger β€” Logs every incoming request with method, URL, and trace ID
  6. Body Parser β€” Parses JSON and URL-encoded bodies (up to 10MB)
  7. Compression β€” Gzip compresses response bodies
  8. Cookie Parser β€” Parses cookies from request headers

πŸ› οΈ Tech Stack

Package Version Purpose
Express.js 5.x Web framework
TypeScript 5.9+ Type-safe JavaScript
Pino 10.x Structured logging
Zod 4.x Schema validation
Helmet 8.x Security headers
express-rate-limit 8.x Rate limiting
ESLint 10.x Code linting
esbuild 0.27+ Fast bundling
TypeDoc 0.28+ API documentation
Nodemon 3.x Development hot-reload

🀝 Contributing

Contributions are welcome! Feel free to open an issue or submit a pull request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request


πŸ“„ License

Licensed under the Apache-2.0. See the LICENSE file for details.


Made with ❀️ by Eldho Paulose

About

TS-BoilerplateX provides developers with a meticulously crafted foundation for building powerful web applications using TypeScript and Express.js, leveraging static typing and flexibility to expedite development while maintaining code integrity and ensuring maintainability.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors