Skip to content

Production-ready Express.js REST API built with TypeScript, TypeDI, routing-controllers, class-validator, and OpenAPI documentation. Features automatic validation, dependency injection, and auto-generated client SDK.

Notifications You must be signed in to change notification settings

fishuke/express-typescript-boilerplate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Express TypeScript OpenAPI Boilerplate

A production-ready Express.js boilerplate with TypeScript, TypeDI, routing-controllers, class-validator, OpenAPI documentation, and auto-generated client SDK using Kubb.

πŸš€ Features

  • TypeScript: Full type safety with strict mode enabled
  • Dependency Injection: Clean architecture with TypeDI
  • Declarative Routing: Type-safe routing with routing-controllers decorators
  • Validation: Automatic request validation with class-validator
  • OpenAPI/Swagger: Auto-generated API documentation from code
  • Client SDK Generation: Type-safe client SDK with Kubb (TypeScript types, Zod schemas, React Query hooks)
  • Error Handling: Centralized error handling middleware
  • CORS: Configured and ready to use
  • Hot Reload: Development server with nodemon
  • Code Quality: ESLint and Prettier configured
  • Real-world Example: Complete CRUD operations for Users and Products

πŸ“‹ Prerequisites

  • Node.js >= 20.0.0
  • npm or yarn or pnpm

πŸ› οΈ Installation

  1. Clone the repository:
git clone [<repository-url>](https://github.com/fishuke/express-typescript-boilerplate.git)
cd express-typescript-boilerplate
  1. Install dependencies:
npm install
  1. Copy environment variables:
cp .env.example .env
  1. Start development server:
npm run dev

The API will be available at:

πŸ“ Project Structure

express-typescript-openapi-boilerplate/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ controllers/        # API controllers with routing-controllers
β”‚   β”‚   β”œβ”€β”€ UserController.ts
β”‚   β”‚   └── ProductController.ts
β”‚   β”œβ”€β”€ services/           # Business logic with TypeDI
β”‚   β”‚   β”œβ”€β”€ UserService.ts
β”‚   β”‚   └── ProductService.ts
β”‚   β”œβ”€β”€ models/             # Data models and interfaces
β”‚   β”‚   β”œβ”€β”€ User.ts
β”‚   β”‚   └── Product.ts
β”‚   β”œβ”€β”€ dto/                # Data Transfer Objects with validation
β”‚   β”‚   β”œβ”€β”€ CreateUserDto.ts
β”‚   β”‚   β”œβ”€β”€ UpdateUserDto.ts
β”‚   β”‚   β”œβ”€β”€ CreateProductDto.ts
β”‚   β”‚   └── UpdateProductDto.ts
β”‚   β”œβ”€β”€ middleware/         # Express middleware
β”‚   β”‚   └── errorHandler.ts
β”‚   β”œβ”€β”€ utils/              # Utility functions
β”‚   β”‚   └── generateOpenApiSpec.ts
β”‚   └── app.ts              # Application entry point
β”œβ”€β”€ client-sdk/             # Auto-generated client SDK (via Kubb)
β”‚   β”œβ”€β”€ types/              # TypeScript types
β”‚   β”œβ”€β”€ zod/                # Zod validation schemas
β”‚   β”œβ”€β”€ client/             # HTTP client functions
β”‚   └── hooks/              # React Query hooks
β”œβ”€β”€ openapi/
β”‚   └── spec.json           # Generated OpenAPI specification
β”œβ”€β”€ kubb.config.ts          # Kubb configuration
β”œβ”€β”€ tsconfig.json           # TypeScript configuration
β”œβ”€β”€ nodemon.json            # Nodemon configuration
β”œβ”€β”€ .eslintrc.json          # ESLint configuration
β”œβ”€β”€ .prettierrc             # Prettier configuration
└── package.json

🎯 API Endpoints

Users

  • GET /api/users - Get all users (with optional role filter)
  • GET /api/users/active - Get active users
  • GET /api/users/:id - Get user by ID
  • POST /api/users - Create a new user
  • PUT /api/users/:id - Update user
  • DELETE /api/users/:id - Delete user

Products

  • GET /api/products - Get all products (with optional category/search filters)
  • GET /api/products/available - Get available products
  • GET /api/products/:id - Get product by ID
  • POST /api/products - Create a new product
  • PUT /api/products/:id - Update product
  • PATCH /api/products/:id/stock - Update product stock
  • DELETE /api/products/:id - Delete product

πŸ”§ Scripts

# Development
npm run dev                 # Start dev server with hot reload

# Build
npm run build              # Compile TypeScript to JavaScript

# Production
npm start                  # Start production server

# Code Generation
npm run generate:openapi   # Generate OpenAPI specification
npm run generate:client    # Generate client SDK with Kubb
npm run generate           # Generate both OpenAPI spec and client SDK

# Code Quality
npm run lint               # Run ESLint
npm run format             # Format code with Prettier

🎨 Tech Stack

Backend

  • Express.js - Fast, unopinionated web framework
  • TypeScript - Type safety and better developer experience
  • TypeDI - Dependency injection container
  • routing-controllers - Declarative routing with decorators
  • class-validator - Decorator-based validation
  • class-transformer - Object transformation
  • routing-controllers-openapi - OpenAPI spec generation

API Documentation

  • Swagger UI Express - Interactive API documentation
  • OpenAPI 3.0 - API specification standard

Client SDK Generation

  • Kubb - OpenAPI to TypeScript code generator
    • TypeScript types generation
    • Zod schemas for runtime validation
    • HTTP client functions
    • TanStack Query (React Query) hooks

πŸ“ Usage Examples

Backend API Example

// Creating a controller
@JsonController('/users')
@Service()
export class UserController {
  constructor(private userService: UserService) {}

  @Get('/')
  @OpenAPI({ summary: 'Get all users' })
  async getAll(): Promise<User[]> {
    return this.userService.findAll();
  }

  @Post('/')
  @HttpCode(201)
  async create(@Body() dto: CreateUserDto): Promise<User> {
    return this.userService.create(dto);
  }
}

Generated Client SDK Example

After running npm run generate, you can use the generated client:

// Using the generated client in your frontend
import { getUsers, createUser } from './client-sdk/client';

// Fetch all users
const users = await getUsers();

// Create a new user
const newUser = await createUser({
  email: 'user@example.com',
  name: 'John Doe',
  role: 'user'
});

Using React Query Hooks (Generated by Kubb)

import { useGetUsers, useCreateUser } from './client-sdk/hooks';

function UsersComponent() {
  // Auto-generated React Query hook with TypeScript types
  const { data: users, isLoading } = useGetUsers();

  const createMutation = useCreateUser();

  const handleCreateUser = () => {
    createMutation.mutate({
      email: 'new@example.com',
      name: 'New User',
      role: 'user'
    });
  };

  return (
    <div>
      {isLoading ? 'Loading...' : users?.map(user => (
        <div key={user.id}>{user.name}</div>
      ))}
      <button onClick={handleCreateUser}>Create User</button>
    </div>
  );
}

πŸ” Validation Example

export class CreateUserDto {
  @IsEmail({}, { message: 'Invalid email address' })
  @IsNotEmpty({ message: 'Email is required' })
  email: string;

  @IsString({ message: 'Name must be a string' })
  @MinLength(2, { message: 'Name must be at least 2 characters long' })
  name: string;

  @IsEnum(UserRole, { message: 'Invalid role' })
  role: UserRole;
}

🚒 Deployment

Build for production:

npm run build

Start production server:

npm start

Docker (optional):

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY dist ./dist
EXPOSE 3000
CMD ["node", "dist/app.js"]

πŸ§ͺ Testing

This boilerplate is ready for testing. You can add:

  • Unit tests with Jest
  • Integration tests with Supertest
  • E2E tests with your preferred framework

πŸ“š Learn More

🀝 Contributing

Contributions, issues, and feature requests are welcome!

πŸ“„ License

This project is MIT licensed.

πŸ‘€ Author

Your Name

⭐ Show your support

Give a ⭐️ if this project helped you!


Note: This is a boilerplate/starter project. In a real-world application, you would typically:

  • Add a database (PostgreSQL, MongoDB, etc.)
  • Implement authentication & authorization (JWT, OAuth)
  • Add logging (Winston, Pino)
  • Add testing (Jest, Supertest)
  • Implement rate limiting
  • Add request/response caching
  • Set up CI/CD pipelines
  • Add monitoring and observability

About

Production-ready Express.js REST API built with TypeScript, TypeDI, routing-controllers, class-validator, and OpenAPI documentation. Features automatic validation, dependency injection, and auto-generated client SDK.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published