Setup & Installation
Bootstrap Express + TypeScript, configure env, and run locally.
Prerequisites
- Node.js 20 LTS, pnpm
- Docker Desktop (for local PostgreSQL / MongoDB)
- AWS Cognito app client configured (see Authentication)
Create a new service
mkdir backend-api && cd backend-api
pnpm init
pnpm add express cors helmet express-rate-limit zod
pnpm add -D typescript tsx @types/express @types/node
npx tsc --initEntry point
// src/server.ts
import { createApp } from "./app";
const PORT = process.env.PORT ?? 4000;
const app = createApp();
app.listen(PORT, () => {
console.log(`API running on http://localhost:${PORT}`);
});// src/app.ts
import express from "express";
import helmet from "helmet";
import cors from "cors";
import { healthRouter } from "./routes/health.routes";
import { v1Router } from "./routes/v1";
import { errorHandler } from "./middleware/error.middleware";
export function createApp() {
const app = express();
app.use(helmet());
app.use(cors({ origin: process.env.CORS_ORIGIN?.split(",") }));
app.use(express.json());
app.use("/health", healthRouter);
app.use("/v1", v1Router);
app.use(errorHandler);
return app;
}Environment variables
cp .env.example .env.localNODE_ENV=development
PORT=4000
CORS_ORIGIN=http://localhost:3000
# Cognito
COGNITO_USER_POOL_ID=us-east-1_xxxxx
COGNITO_REGION=us-east-1
COGNITO_CLIENT_ID=xxxxxxxx
# PostgreSQL (Sequelize or Drizzle)
DATABASE_URL=postgres://user:password@localhost:5432/app
# MongoDB
MONGODB_URI=mongodb://localhost:27017/app
# Supabase
SUPABASE_URL=https://xxxx.supabase.co
SUPABASE_SERVICE_ROLE_KEY=eyJ... # Server only — never expose to clientLocal dependencies
docker compose up -d postgres mongo
docker compose ps# docker-compose.yml
services:
postgres:
image: postgres:16-alpine
ports: ["5432:5432"]
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: app
mongo:
image: mongo:7
ports: ["27017:27017"]Scripts
{
"scripts": {
"dev": "tsx watch src/server.ts",
"build": "tsc",
"start": "node dist/server.js",
"lint": "eslint src/",
"typecheck": "tsc --noEmit",
"test": "vitest run"
}
}Verify
pnpm dev
curl http://localhost:4000/health
# {"status":"ok","service":"backend-api"}- Health endpoint returns 200.
pnpm lint && pnpm typecheck && pnpm testpass.- Database connection succeeds (see your ORM guide).
- Authenticated
/v1/request with Cognito token works.