A production-ready Express.js boilerplate built with TypeScript, designed to provide a robust, scalable, and secure foundation for your next Node.js API project. This template comes with essential features like strong security, high code quality, and developer-friendly tools, enabling you to focus on building your application while ensuring maintainability and performance right from the start.
- Web framework: Fast and minimalist web application framework using express
- Logging: Advanced logging with winston and morgan
- Schema validation: Ensure the integrity of incoming requests (query params, body) using zod
- Environment Variable Management: Ensures all required environment variables are present and properly validated using zod
- Error handling: Comprehensive error management system
- Signal handling: Gracefully handles OS signals like
SIGTERMandSIGINTto ensure proper cleanup and shutdown of the application - API Documentation: Automatic OpenAPI/Swagger documentation generation using zod-openapi, seamlessly integrated with Zod schemas to provide always up-to-date API documentation
- CORS protection: Manage cross-origin requests with cors
- Helmet: Help secure Express apps by setting HTTP response headers with helmet
- Rate limiting: Safeguard the API against excessive requests and potential DDoS attacks with efficient middleware provided by express-rate-limit
- Secure authentication: Robust JWT-based authentication implemented using jsonwebtoken, jwks-rsa and jwt-decode. Public keys are fetched from Microsoftβs identity platform, tokens are decoded and verified, and user informations (like
usernameandgroups) are extracted. Tokens are validated against audience and issuer claims to ensure only authorized clients can access the API.
- Code formatting: Consistent code style with oxfmt
- Linting: Enforce best practices and maintainable code with oxlint
- Git Hooks with Husky: Automated quality gates using husky to enforce standards on every commit:
-
Pre-commit hook β Runs the following checks before allowing a commit:
- Unit tests to prevent commits that would break the test suite
- Lint and format staged files via lint-staged (oxlint auto-fix + oxfmt)
{ "*.{js,jsx,ts,tsx}": ["npm run lint:fix"], "*.{js,jsx,ts,tsx,md,html,css}": ["npm run format"] } npm auditto check for known vulnerabilities- TypeScript type checking to catch type errors
-
Commit-msg hook β Enforces Conventional Commits format using commitlint
-
This boilerplate includes automatic OpenAPI/Swagger documentation generation that keeps your API docs always in sync with your code.
- Automatic Generation: Documentation is automatically generated from your Zod schemas using
zod-openapi - Type Safety: Leverages TypeScript and Zod for type-safe API definitions
- Multiple Formats: Generates both JSON and YAML formats for maximum compatibility
- Rich Descriptions: Supports detailed descriptions, examples, and metadata for each endpoint
- Generate Documentation: Run
npm run openapito generate the latest API documentation - View Documentation: The generated files are saved in the
docs/directory:docs/openapi.json- JSON format for programmatic usedocs/openapi.yaml- YAML format for human readability
- Schema Definitions: API schemas are defined in
src/models/with OpenAPI extensions - Route Definitions: OpenAPI route configurations are in
src/openapi/routes/
import { z } from 'zod'
export const userSchema = z
.strictObject({
id: z.string().uuid(),
name: z.string().min(1).max(100),
email: z.string().email(),
})
.meta({
description: 'User object with basic information',
id: 'User'
example: {
id: '123e4567-e89b-12d3-a456-426614174000',
name: 'John Doe',
email: 'john.doe@example.com',
},
})The documentation can be viewed using any OpenAPI/Swagger UI tool or integrated into your API gateway.
-
Code coverage: Ensure high code quality and test coverage with Vitestβs built-in coverage reporting
- Hot-reload: Streamline development with automatic server reload using Node's native
--watch
- Azure Key Vault Integration: Securely manage secrets using azure/identity and azure/keyvault-secrets
- Docker support: Containerization for easy deployment
- HTTP Status Codes: Simplified status code management with http-status-codes
- Clone the repository
git clone https://github.com/ToniR7/express-typescript-starter.git cd express-typescript-starter - Install dependecies:
npm install - Set up your environment variables (you can use the
.env.testfile as a reference to create your own.envfile) - Run the development server:
npm run dev
project-name/
β
βββ .github/ # GitHub configuration
β βββ workflows/ # GitHub Actions workflow definitions
β βββ ci.yml # CI pipeline (lint, security scan, typecheck, test)
β
βββ .husky/ # Git hooks managed by Husky
β βββ pre-commit # Pre-commit hook (tests, linting, audit, typecheck)
β βββ commit-msg # Commit message linting with commitlint
β
βββ docs/ # Generated documentation
β βββ openapi.json # OpenAPI specification in JSON format
β βββ openapi.yaml # OpenAPI specification in YAML format
βββ node_modules/ # Installed dependencies
β
βββ src/ # Source code
β βββ apis/ # Request handlers for different routes
β βββ environment/ # Configuration and environment variable management
β βββ errors/ # Custom errors definition
β βββ logger/ # Logging utilities (Winston and Morgan)
β βββ middlewares/ # Express middleware functions (authentication, validation, error handling, rate limit)
β βββ models/ # Schemas definition (Zod schemas with OpenAPI extensions)
β βββ openapi/ # OpenAPI documentation generation
β βββ routes/ # API route definitions
β βββ typings/ # TypeScript type definitions and interfaces
β βββ utils/ # Utility functions and helper modules
β βββ app.ts # Entry point of the application, initializes the server
β
βββ .commitlintrc # Commitlint configuration (Conventional Commits)
βββ .dockerignore # Files and directories to exclude from Docker builds
βββ .env # Environment variables (local development)
βββ .env.test # Example environment variables file (for documentation)
βββ .gitignore # Files and directories to ignore in Git
βββ .lintstagedrc # Configuration for lint-staged to run linting and formatting on staged files
βββ .npmrc # npm configuration
βββ .nvmrc # Specifies the Node.js version to use (for nvm compatibility)
βββ .oxfmtrc.json # Oxfmt configuration file for code formatting
βββ .oxlintrc.json # Oxlint configuration for linting the codebase
βββ Dockerfile # Instructions to build a Docker image of the project
βββ LICENSE # Project license
βββ package-lock.json # Lockfile for package versions
βββ package.json # Project metadata, dependencies, and scripts
βββ README.md # Project documentation and setup instructions
βββ tsconfig.json # TypeScript configuration for development and tooling
βββ vitest.config.ts # Vitest configuration for running tests
npm run test: Runs Vitest tests. It will execute all the test cases written in the project without coverage reporting.npm run test:coverage: Runs Vitest tests with coverage reporting. It generates a code coverage report showing which parts of the code are covered by tests.npm run test:watch: Runs Vitest tests in watch mode. It watches for changes in the codebase and automatically reruns tests when files are modified.
npm run updates: Runs npm-check-updates, a tool that checks for the latest versions of dependencies in the package.json and shows which packages can be updated.npm run updates:interactive: Runs npm-check-updates in interactive mode, allowing you to select which packages to update.npm run updates:upgrade: Automatically update the versions of dependencies in the package.json to the latest versions.
npm run depcheck: Runs depcheck, a tool that checks how each dependency is used, which dependencies are useless, and which dependencies are missing from package.json
npm run openapi: Generates OpenAPI/Swagger documentation from Zod schemas. Creates openapi.json and openapi.yaml files containing the complete API specification that can be used with Swagger UI or other OpenAPI tools.
npm run lint: Runs oxlint to check for issues in the code. It will output warnings and errors according to the rules defined in the oxlint configuration.npm run lint:fix: Runs oxlint with the --fix flag, which automatically fixes any issues it can. Itβs useful for cleaning up common problems.npm run format: Runs oxfmt to format the code. It will rewrite the code to follow a consistent style, ensuring things like indentation and line breaks are uniform across the codebase.npm run format:check: Runs oxfmt in check mode. It verifies that files conform to the formatting rules without modifying them, returning a non-zero exit code if differences are found (useful for CI pipelines).npm run lint-staged: Runs lint-staged, which executes oxlint and oxfmt only on staged files according to the configuration in .lintstagedrc. This allows for faster pre-commit checks by only processing files that are about to be committed rather than the entire codebase.
npm run dev: Runs the development server. This tool watches for changes in TypeScript files and automatically restarts the server.npm run debug: Runs the server in debugging mode using the --inspect flag. This allows to attach a debugger to the Node.js process, enabling step-through debugging.
npm run typecheck: Runs the TypeScript compiler with--noEmitto check for type errors without producing output files.
npm run prod: Runs the application directly with Node.js (using native TypeScript support). This script is for running the app in production.
npm run prepare: Runs the Husky setup. It prepares the Git hooks (like pre-commit and commit-msg hooks) by setting up the necessary files. This is typically used after installing or updating Husky.
This project includes a CI Pipeline (.github/workflows/ci.yml) that runs automatically on:
- Push to
mainordevelopbranches - Pull requests targeting
mainordevelop(on open and synchronize events)
| Job | Description |
|---|---|
| lint | Installs dependencies and runs npm run lint to check code quality with oxlint |
| security-scan | Runs CodeQL static analysis for TypeScript to detect security vulnerabilities |
| typecheck | Runs npm typecheck to ensure the codebase has no TypeScript type errors |
| test | Runs npm test to execute the full test suite with Vitest |
All four jobs run in parallel since they have no dependencies on each other, providing fast feedback on pull requests.
I welcome contributions through:
- π Bug Reports
- π‘ Feature Requests
- π Documentation Improvements
- π οΈ Code Contributions
