TypeScript and Express is the most popular combination for building Node.js backend APIs. This tutorial takes you from zero to a production-ready REST API.
Why TypeScript with Express?
Plain JavaScript Express apps break silently. TypeScript catches errors at compile time:
- Type safety: Catch bugs before they reach production
- Better IDE support: Autocomplete for routes, middleware, and request/response objects
- Self-documenting: Types serve as living documentation
- Refactor confidently: Rename a field and TypeScript shows every place that needs updating
Project Setup
Initialize your project:
mkdir my-api && cd my-api
npm init -y
npm install express
npm install -D typescript @types/express @types/node ts-node nodemonCreate tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "commonjs",
"lib": ["ES2022"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}Basic Express Server
Create src/index.ts:
import express, { Request, Response } from "express";
const app = express();
const PORT = process.env.PORT || 3000;
app.use(express.json());
app.get("/health", (req: Request, res: Response) => {
res.json({ status: "ok", timestamp: new Date().toISOString() });
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});Add scripts to package.json:
{
"scripts": {
"dev": "nodemon --exec ts-node src/index.ts",
"build": "tsc",
"start": "node dist/index.js"
}
}Run the dev server:
npm run devMaster this topic with hands-on labs
Go beyond reading — build real projects in sandboxed environments with expert video guidance.
Browse Courses →Typed Route Handlers
Define your data types:
interface User {
id: string;
name: string;
email: string;
createdAt: Date;
}
const users: User[] = [];Create typed CRUD routes:
// GET all users
app.get("/api/users", (req: Request, res: Response) => {
res.json(users);
});
// GET user by ID
app.get("/api/users/:id", (req: Request, res: Response) => {
const user = users.find((u) => u.id === req.params.id);
if (!user) {
res.status(404).json({ error: "User not found" });
return;
}
res.json(user);
});
// POST create user
app.post("/api/users", (req: Request, res: Response) => {
const { name, email } = req.body as { name: string; email: string };
const user: User = {
id: crypto.randomUUID(),
name,
email,
createdAt: new Date(),
};
users.push(user);
res.status(201).json(user);
});Middleware
Error handling middleware with proper types:
import { NextFunction } from "express";
function errorHandler(
err: Error,
req: Request,
res: Response,
next: NextFunction
) {
console.error(err.stack);
res.status(500).json({
error: "Internal Server Error",
message:
process.env.NODE_ENV === "development" ? err.message : undefined,
});
}
app.use(errorHandler);Request validation middleware:
function validateBody(requiredFields: string[]) {
return (req: Request, res: Response, next: NextFunction) => {
const missing = requiredFields.filter(
(field) => !(field in req.body)
);
if (missing.length > 0) {
res
.status(400)
.json({ error: `Missing fields: ${missing.join(", ")}` });
return;
}
next();
};
}
app.post("/api/users", validateBody(["name", "email"]), createUser);Project Structure
Organize larger projects into modules:
src/
index.ts # App entry point
routes/
users.ts # User routes
products.ts # Product routes
middleware/
auth.ts # Authentication
validation.ts # Request validation
types/
index.ts # Shared type definitions
services/
user.service.ts # Business logicGet weekly IT automation tips
Docker, Ansible, Terraform, MLOps — curated insights delivered to your inbox. No spam.
Subscribe Free →Router Modules
Separate routes into files with express.Router():
// src/routes/users.ts
import { Router, Request, Response } from "express";
const router = Router();
router.get("/", (req: Request, res: Response) => {
res.json({ users: [] });
});
router.post("/", (req: Request, res: Response) => {
// Create user logic
res.status(201).json({ message: "Created" });
});
export default router;Mount in your main app:
import userRoutes from "./routes/users";
app.use("/api/users", userRoutes);Build and Deploy
npm run build # Compiles to dist/
npm start # Runs compiled JSFor Docker:
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/index.js"]What's Next?
Our Node.js REST APIs course goes deeper — database integration with Prisma, JWT authentication, testing, and production deployment patterns. The first lesson is free.
---
Ready to go deeper?
This article is part of a hands-on learning path. Continue building your skills with Node.js REST APIs on CopyPasteLearn.
Ready to learn by doing?
Stop reading tutorials — start building. Expert video courses with hands-on labs in real sandboxed environments.
Related Articles
Building REST APIs with Node.js
Learn how to build production-ready REST APIs with Node.js and Express — routing, middleware, error handling, and best practices.
Docker Compose for Dev Environments
Set up reproducible local development environments with Docker Compose. Multi-service stacks, hot reload, database seeding, and team workflows.
Git for DevOps Engineers
Essential Git workflows for DevOps: branching strategies, interactive rebasing, cherry-picking, bisect debugging, and CI/CD integration.
Ubuntu 24.04 LTS: Safe Choice
Ubuntu 24.04 LTS offers five years of support, the largest ecosystem, and unmatched hardware compatibility. Why it remains the safest mainstream Linux choice.
Ubuntu 26.04 Makes sudo-rs Default
Ubuntu 26.04 LTS replaces the 44-year-old C sudo with sudo-rs, a Rust rewrite. Learn what changes, why it matters for security, and what else ships.
Ubuntu vs Fedora: Which to Pick
Ubuntu and Fedora are the two most popular Linux desktop distros. A practical comparison to help you decide which fits your workflow.
Explore topics
Browse more articles on the topics covered here.