npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ts-boilerplatex

v3.0.0

Published

TS-BoilerplateX is a meticulously crafted boilerplate tailored for developers seeking a seamless starting point for building powerful web applications with TypeScript and Express.js. With TS-BoilerplateX, harness the combined benefits of TypeScript's stat

Readme

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": "[email protected]",
      "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": "[email protected]",
    "age": 30,
    "role": "moderator"
  }'

Response (201):

{
  "success": true,
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "Alice Johnson",
    "email": "[email protected]",
    "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

🔗 Resizo.in — Free Image Resizer · No Upload · No Sign-up · No Watermarks

https://www.resizo.in/


📄 License

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