A production-grade Express.js + TypeScript backend with Docker support, structured logging, centralized error handling, and code quality tooling out of the box.
| Tool | Purpose |
|---|---|
| Node.js LTS | Runtime |
| TypeScript 5 | Type safety |
| Express.js 4 | HTTP framework |
| Helmet + CORS | Security headers |
| dotenv | Environment config |
| ESLint + Prettier | Code quality |
| ts-node-dev | Hot-reload dev server |
| Docker + Compose | Containerization |
abbot/
├── src/
│ ├── config/ # Env config loader (typed)
│ ├── controllers/ # Request handlers
│ ├── middleware/ # Error handler, request logger, 404
│ ├── routes/ # Express routers
│ ├── services/ # Business logic (framework-agnostic)
│ └── utils/ # Logger, response helpers, error classes
│ ├── logger.ts
│ ├── apiResponse.ts
│ └── errors.ts
├── .env.example # Environment template
├── .eslintrc.json
├── .prettierrc
├── tsconfig.json
├── Dockerfile # Multi-stage production build
└── docker-compose.yml # Local development setup
- Docker Desktop installed and running
git clone <your-repo-url>
cd abbot
cp .env.example .envdocker-compose up --buildThe API will be available at http://localhost:3000/api/v1/health
# Install dependencies
npm install
# Start hot-reload dev server
npm run dev
# In another terminal — lint and format
npm run lint
npm run format| Script | Description |
|---|---|
npm run dev |
Start dev server with hot-reload (ts-node-dev) |
npm run build |
Compile TypeScript → dist/ |
npm start |
Run compiled production build |
npm run lint |
Check for ESLint violations (zero-warning mode) |
npm run lint:fix |
Auto-fix ESLint violations |
npm run format |
Format all source files with Prettier |
npm run format:check |
Verify formatting without writing |
npm run type-check |
TypeScript type check without emit |
npm run clean |
Delete dist/ directory |
Copy .env.example to .env and fill in values:
NODE_ENV=development
PORT=3000
LOG_LEVEL=debug
API_PREFIX=/api/v1
CORS_ORIGIN=*docker build --target production -t abbot:latest .docker run -p 3000:3000 --env-file .env abbot:latest| Method | Path | Description |
|---|---|---|
GET |
/api/v1/health |
Liveness probe |
- Service →
src/services/myFeature.service.ts(business logic, no Express types) - Controller →
src/controllers/myFeature.controller.ts(handles req/res, calls service) - Route →
src/routes/myFeature/index.ts(defines endpoints) - Register → Add to
src/routes/index.ts
All errors flow through the centralized errorHandler middleware:
AppErrorsubclasses → operational errors, client-safe messages sent- Unexpected errors → stack hidden in production,
500 Internal Server Errorreturned
MIT