Reusable TypeScript service template for integration-facing services. This is a generic foundation — it contains no product logic, only service plumbing.
Intended for things like:
- Slack adapters
- MCP servers
- Webhook receivers
- Lightweight integration APIs
- Node 24+ (pinned in
.nvmrc)
# Install dependencies
npm install
# Copy env file and fill in values
cp .env.example .env
# Run the dev server (hot reload)
npm run devThe service is available at http://localhost:3001.
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch# Format, lint, typecheck, and test
npm run precommit| Method | Path | Description |
|---|---|---|
| GET | /healthz |
Health check |
- App factory:
buildApp(opts?)creates a configured Fastify instance — testable in isolation - Composition root:
server.tsis the only file that reads env vars - Env validation: Zod schema with fail-fast on startup
- Error handling:
AppErrorclass → consistent{ error: { code, message, details } }envelope - Request logging: Structured pino logs with request_id, method, url, status_code, duration_ms
- Core API client: Typed
CoreApiClientfor calling backend services (constructor injection, no env coupling)
See docs/ARCHITECTURE.md for detailed design and docs/DECISIONS.md for the decision log.
Copy .env.example to .env. Dev requires:
| Variable | Default | Description |
|---|---|---|
PORT |
3001 | HTTP port |
HOST |
0.0.0.0 | Bind address |
LOG_LEVEL |
info | Pino log level |
CORE_API_BASE_URL |
— | Backend API URL (required) |
CORE_API_TOKEN |
— | Bearer token for backend API (required) |
This is one of three reusable service templates. They share API conventions and response envelopes but are otherwise independent.
| Template | Purpose | Stack |
|---|---|---|
| elixir-api-core | Core backend APIs | Elixir, Phoenix, PostgreSQL |
| node-edge-core (this repo) | Edge/integration services | TypeScript, Fastify, Zod |
| web-app-core | Frontend SPA | TypeScript, React, Vite, Tailwind |
Product apps are created from these templates and then diverge freely with domain logic. They're designed to work together — a frontend built from web-app-core calls a backend API built from elixir-api-core, while edge services built from node-edge-core handle integrations.
This repo is intended to work as a standalone starting point. It does not require the companion templates to exist locally in the same directory. If you want to pair it with the related backend or frontend templates, use the GitHub repos above rather than assuming a shared workspace layout.
See CHANGELOG.md for the versioned task tracker.