Introduction
Modern web development is unthinkable without a REST API. It is the foundation on which mobile applications, SPA frontends, and microservices are built. If you are a beginner and want to quickly learn backend development, the TypeScript + Express stack is an ideal start. TypeScript adds strict typing to JavaScript, making the code more reliable and understandable, especially when working in a team.
In this guide, we will create a full-fledged REST API for managing a task list (Todo list) in 30 minutes. You will learn how to set up a project, describe data models, create routes, and connect a database. No unnecessary theory — just practice and ready-to-run code.
It is assumed that you already have Node.js (version 18+) and npm installed. If not, download them from the official website.
1. Project Setup and Dependency Installation
Let's start by initializing a new TypeScript project. Open the terminal and run the commands:
mkdir my-todo-apicd my-todo-apinpm init -yNow install the necessary packages:
npm install expressnpm install -D typescript @types/node @types/express ts-node nodemonCreate the TypeScript configuration file:
npx tsc --initIn the tsconfig.json file, make sure the following lines are uncommented and configured:
{ "compilerOptions": { "target": "ES2020", "module": "commonjs", "outDir": "./dist", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"]}Create the src folder and the src/index.ts file — this will be the entry point of our application.
Add scripts to package.json for convenient launch:
"scripts": { "dev": "nodemon --exec ts-node src/index.ts", "build": "tsc", "start": "node dist/index.js"}2. Creating a Basic Express Server
Now let's write a minimal Express server that will listen on port 3000. Open src/index.ts and add the following code:
import express, { Request, Response } from 'express';
const app = express();const PORT = 3000;
// Middleware for parsing JSONapp.use(express.json());
// Basic route for testingapp.get('/', (req: Request, res: Response) => { res.send('Todo API is working!');});
app.listen(PORT, () => { console.log(`Server running at http://localhost:${PORT}`);});Start the server with the command npm run dev and open the browser at http://localhost:3000. You should see the message "Todo API is working!".
3. Defining the Data Model and In-Memory Storage
For simplicity, we will not connect a database right away, but will use temporary storage in RAM. Create the file src/models/todo.ts:
export interface Todo { id: number; title: string; completed: boolean; createdAt: Date;}
export let todos: Todo[] = [ { id: 1, title: 'Learn TypeScript', completed: false, createdAt: new Date() }, { id: 2, title: 'Write a REST API', completed: false, createdAt: new Date() },];Notice the use of the Todo interface — this ensures that all objects in the array have the same structure.
4. Implementing CRUD Routes
Let's create the file src/routes/todos.ts with full routes for Create, Read, Update, and Delete operations.
import { Router, Request, Response } from 'express';import { Todo, todos } from '../models/todo';
const router = Router();
// GET /api/todos — get all tasksrouter.get('/', (req: Request, res: Response) => { res.