A production-grade REST API boilerplate for Node 24 · TypeScript 7 · Hono 4 · Drizzle · Postgres 17, with the agentic-kit built in: one AGENTS.md every AI coding agent reads, skills that encode how to add endpoints and migrations, hooks that block destructive commands and force just check to pass before an agent can say "done", and a multi-model (Claude + Codex + Gemini) code-review council in CI.
It is opinionated on purpose. TypeScript runs directly on Node via type stripping (no build step in dev), validation and OpenAPI come from one zod schema, every query is owner-scoped, tests run on an in-memory Postgres (PGlite) in under five seconds with no Docker, and the reference notes module shows the exact shape every new resource should copy.
git clone https://github.com/kalpesh122/agentic-backend-node my-api && cd my-api
cp .env.example .env # defaults work locally
just setup # corepack + pnpm install
just docker-up # Postgres 17 on localhost:5433
just db-migrate # apply drizzle/*.sql
just dev # http://localhost:3000/docsThen open Claude Code (or Codex / Cursor / Gemini CLI) in the folder and ask for a new resource; the add-endpoint skill drives the rest.
Requirements: Node 24 (.node-version), just, Docker (only for the dev database; tests do not need it).
| Command | What it does |
|---|---|
just setup |
Install dependencies (pnpm 12 via corepack) |
just dev |
Watch-mode API on PORT (3000) with pretty logs |
just test [pattern] |
Vitest on PGlite (no Docker) |
just lint / just fmt |
Biome check / fix |
just typecheck |
tsc --noEmit with TypeScript 7 |
just build |
Compile to dist/ for the Docker image |
just check |
Quality gate: lint + typecheck + test + build |
just db-generate / just db-migrate / just db-studio |
Drizzle migrations and studio |
just docker-up / just docker-down / just docker-build |
Dev Postgres and the production image |
just council |
Local multi-model code review of your branch |
| Concern | Choice | Why |
|---|---|---|
| HTTP | Hono 4 + @hono/zod-openapi |
Web-standard, plain functions, one schema → validation + OpenAPI; docs at /docs via Scalar |
| Runtime | Node 24 type stripping, TypeScript 7 for checking | No bundler, no transpile step; tsc --noEmit is the type gate |
| Database | Drizzle 0.45 + postgres driver + generated SQL migrations |
Typed queries, migrations you can read, no runtime magic |
| Tests | Vitest 4 + PGlite | Real Postgres semantics in-process; each file gets a fresh DB |
| Auth | better-auth (email + password, cookie sessions) at /api/auth/* |
Modern, drizzle-native, easy to extend with OAuth providers |
| Jobs | pg-boss | Reliable queue on the DB you already run; no Redis |
| Logging | pino with request ids and redaction | Structured JSON in prod, pretty in dev |
| Tracing | OpenTelemetry, opt-in via OTEL_EXPORTER_OTLP_ENDPOINT |
Zero cost when unset |
| Rate limit | hono-rate-limiter on /api/* |
Sensible default, swap the store for Redis when horizontal |
| Errors | AppError → { error: { code, message, details?, requestId } } |
One shape for humans, clients, and agents |
| Lint/format | Biome 2 | Fast, single tool, unaffected by the TS 7 compiler-API gap |
src/index.ts bootstrap (env → logger → otel → db → auth → jobs → app → serve → graceful shutdown)
src/app.ts createApp(deps): middleware order, routes, OpenAPI, error handler
src/env.ts zod-validated config; fails fast with every problem listed
src/db/ schema.ts · client.ts · migrate.ts drizzle/ generated SQL
src/lib/ auth · session · errors · jobs · logger · otel
src/modules/notes/ schema → routes → service → repo (+ tests) ← copy this for new resources
src/modules/health/ /health, /ready
test/helpers.ts createTestContext(): PGlite + migrations + sign-up + fetch
.claude/ .agents/ AGENTS.md the agentic kit (see below)
GET /health /ready /docs /openapi.json
POST /api/auth/sign-up/email POST /api/auth/sign-in/email POST /api/auth/sign-out GET /api/auth/get-session
GET /api/notes?limit=20&cursor=… POST /api/notes GET|PATCH|DELETE /api/notes/:id
All /api/notes routes require a session cookie and only ever return the caller's rows.
AGENTS.md(≤150 lines) is the map: commands, layout, hard rules, definition of done.CLAUDE.mdimports it; Gemini, Copilot, and Cursor point at it.- Skills in
.claude/skills/(mirrored in.agents/skills/for other tools):add-endpoint,add-migration, plus the kit'sbrainstorm-spec,tdd,debug,code-review,council-review,verify-before-done,adr,git-hygiene. - Hooks in
.claude/settings.json: blockrm -rf, force pushes,DROP TABLE, reading.env; protect lockfiles; format every edited file with Biome; runjust checkwhen the agent tries to stop and block if it fails. - Subagents: read-only
planner,reviewer,security-reviewer,explorer; write-capabletdd-implementer;council-synthesizer. - CI:
ci.ymlrunsjust checkand a Docker build;ai-council-review.ymlhas three models review every PR against.github/review-rubric.mdand posts one consolidated comment (addANTHROPIC_API_KEY, optionallyOPENAI_API_KEYandGEMINI_API_KEY, as secrets). specs/001-notes/shows the spec → plan → tasks flow the kit expects;docs/adr/records why the stack looks like this.
- Postgres provider: change
DATABASE_URL; Neon/Supabase work as-is with thepostgresdriver. - Auth: add OAuth providers in
src/lib/auth.ts(socialProviders); or replacesessionMiddlewarewith a JWT verifier and keeprequireUser. - Jobs: implement the
JobQueueinterface insrc/lib/jobs.tswith BullMQ if you already run Redis. - Rate-limit store: pass a Redis store to
rateLimiterinsrc/app.tswhen running more than one instance. - Bundled deploy:
just buildemitsdist/; the Dockerfile runs migrations then the server.
MIT © Kalpesh Mali