A professional, production-ready Express.js backend starter template built with TypeScript, featuring clean architecture, comprehensive middleware, and best practices.
- β TypeScript - Full type safety and modern JavaScript features
- β Clean Architecture - Separation of concerns with layered structure
- β Error Handling - Comprehensive error handling with custom error classes
- β Request Validation - Schema-based validation using AJV
- β Rate Limiting - Configurable rate limiting to prevent abuse
- β Security - Security headers with Helmet
- β CORS - Configurable cross-origin resource sharing
- β Logging - HTTP request logging with Morgan
- β Health Checks - Health, readiness, and liveness endpoints
- β Environment Config - Environment-based configuration
- β ESLint - Code quality and consistency
- β Docker Support - Ready for containerization
express-typescript-starter/
βββ src/
β βββ config/ # Configuration files
β β βββ config.ts # Environment and app configuration
β βββ controllers/ # Request handlers
β β βββ health.controller.ts
β β βββ user.controller.ts
β β βββ index.ts
β βββ middleware/ # Custom middleware
β β βββ errorHandler.ts
β β βββ notFoundHandler.ts
β β βββ rateLimiter.ts
β β βββ validateRequest.ts
β βββ routes/ # Route definitions
β β βββ index.ts
β β βββ health.routes.ts
β β βββ user.routes.ts
β βββ services/ # Business logic layer (add your services here)
β βββ types/ # TypeScript type definitions
β β βββ common.types.ts
β βββ utils/ # Utility functions and helpers
β β βββ apiResponse.ts
β β βββ appError.ts
β β βββ asyncErrorHandler.ts
β βββ validation/ # Validation schemas
β β βββ index.ts
β β βββ userSchema.ts # User validation schema
β βββ app.ts # Express app setup
β βββ server.ts # Server entry point
βββ .env.example # Example environment variables
βββ .gitignore
βββ Dockerfile # Multi-stage Docker build
βββ compose.yaml # Docker Compose configuration
βββ eslint.config.mts # ESLint configuration
βββ package.json
βββ tsconfig.json # TypeScript configuration
βββ README.md
- Node.js (v16 or higher)
- npm or yarn
-
Clone or download this template:
git clone https://github.com/Tushar1357/express-typescript-starter-template.git cd express-typescript-starter -
Install dependencies:
npm install
-
Create environment file:
cp .env.example .env
-
Configure your environment variables in
.env
Development mode with hot reload:
npm run devBuild for production:
npm run buildStart production server:
npm startLint code:
npm run lintFix linting issues:
npm run lint:fixGET /health- Basic health checkGET /api/health- Detailed health informationGET /api/health/readiness- Readiness probe (for Kubernetes)GET /api/health/liveness- Liveness probe (for Kubernetes)
GET /api/users- Get all usersGET /api/users/:id- Get user by IDPOST /api/users- Create new user{ "name": "John Doe", "email": "[email protected]", "age": 30 }PUT /api/users/:id- Update userDELETE /api/users/:id- Delete user
-
Routes Layer (
src/routes/)- Define API endpoints
- Map HTTP methods to controller actions
- Apply route-specific middleware
-
Controllers Layer (
src/controllers/)- Handle HTTP requests and responses
- Validate request data
- Call service layer methods
- Format responses using ApiResponse utility
-
Services Layer (
src/services/)- Contain business logic
- Interact with data models/databases
- Handle data processing
- Add your service files here
-
Middleware Layer (
src/middleware/)- Request/response processing
- Error handling
- Validation
- Rate limiting
-
Utils Layer (
src/utils/)- Reusable utility functions
- Custom error classes
- Response formatters
- Express.js - Fast, unopinionated web framework
- TypeScript - Type safety and better developer experience
- AJV - JSON schema validation
- Helmet - Security headers
- Morgan - HTTP request logger
- CORS - Cross-origin resource sharing
- http-status-codes - HTTP status constants
- express-rate-limit - Rate limiting middleware
See .env.example for all available configuration options.
Key variables:
NODE_ENV- Environment (development/production/test)PORT- Server port (default: 3000)CORS_ORIGIN- Allowed CORS origins (default: *)API_PREFIX- API route prefix (default: /api)RATE_LIMIT_WINDOW_MS- Rate limit window in millisecondsRATE_LIMIT_MAX_REQUESTS- Max requests per window
- Create a controller in
src/controllers/ - Create routes in
src/routes/ - Add validation schema in
src/validation/(if needed) - Create service in
src/services/for business logic - Mount routes in
src/routes/index.ts
// src/controllers/blog.controller.ts
export const getAllPosts = asyncErrorHandler(async (req, res) => {
const posts = await blogService.getAllPosts();
return ApiResponse.success(res, posts);
});
// src/routes/blog.routes.ts
import { Router } from 'express';
import { getAllPosts } from '../controllers/blog.controller';
const router = Router();
router.get('/', getAllPosts);
export default router;
// src/routes/index.ts
import blogRoutes from './blog.routes';
router.use('/blog', blogRoutes);This project includes a production-ready multi-stage Dockerfile and Docker Compose configuration.
- Docker (v20.10 or higher recommended)
- Docker Compose v2
Start the application:
npm run docker:startStop the application:
npm run docker:stopRestart the application:
npm run docker:restartYour application will be available at http://localhost:3000.
The Dockerfile uses a multi-stage build for optimal image size:
- deps - Installs production dependencies only
- build - Installs all dependencies and builds TypeScript
- final - Minimal runtime image with only production dependencies and compiled code
-
Build for your target platform:
# For amd64 (most cloud providers) docker build --platform=linux/amd64 -t myapp .
-
Tag and push to your registry:
docker tag myapp myregistry.com/myapp:latest docker push myregistry.com/myapp:latest
The compose.yaml includes a commented PostgreSQL example. Uncomment and configure as needed:
services:
server:
depends_on:
db:
condition: service_healthy
db:
image: postgres
# ... see compose.yaml for full configuration(Add your testing framework and tests)
npm testMIT
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Use the
asyncErrorHandlerwrapper for all async route handlers - Always validate request data using schemas
- Use
ApiResponseutility for consistent response formatting - Throw
AppErrorfor operational errors - Keep business logic in the service layer
- Add your database/ORM setup in the config folder
- Update rate limits based on your application needs
Happy Coding! π