Skip to content

ADR 001 Server Framework

Claude product-architect (Opus 4.6) edited this page Feb 22, 2026 · 2 revisions

ADR-001: Server Framework

Status

Accepted

Context

Cornerstone needs a Node.js HTTP server framework to serve the REST API and static client assets. The framework must support:

  • TypeScript-first development
  • Plugin architecture for modular feature registration (auth, database, routes)
  • JSON schema validation for request/response
  • Static file serving for the bundled SPA
  • OIDC authentication middleware (or ecosystem support)
  • Session/cookie management
  • Proxy capabilities (for Paperless-ngx API)
  • Good performance for <5 concurrent users (not a hard requirement given scale)

Alternatives Considered

Express (v4/v5)

  • The most widely used Node.js framework with the largest ecosystem
  • Weak TypeScript support; types are community-maintained and often lag behind
  • Middleware-based architecture can lead to ordering bugs
  • No built-in validation; requires additional libraries (Joi, Zod, etc.)
  • Express v5 is still not fully stable
  • Performance adequate for this scale

Hono

  • Lightweight, fast, excellent TypeScript support
  • Designed for edge runtimes (Cloudflare Workers, Deno, Bun) but works with Node.js
  • Smaller ecosystem; fewer battle-tested plugins for OIDC, sessions, and database
  • Less mature for traditional server-side Node.js applications
  • Static file serving and SPA fallback require more manual setup

Fastify (v5)

  • Excellent TypeScript support with typed plugins and decorators
  • Plugin system enforces encapsulation and modularity
  • Built-in JSON schema validation (using AJV) and serialization
  • @fastify/static for serving SPA assets with SPA fallback
  • Rich ecosystem: @fastify/cookie, @fastify/session, @fastify/oauth2, @fastify/reply-from (proxy)
  • Actively maintained with predictable release cycles
  • Slightly higher learning curve than Express due to plugin encapsulation model

Decision

Use Fastify v5 as the server framework.

Consequences

Positive

  • Type-safe route definitions reduce runtime errors
  • Plugin encapsulation keeps auth, database, and route concerns separated
  • Built-in validation eliminates the need for a separate validation library
  • The @fastify/static plugin handles SPA serving with fallback out of the box
  • The @fastify/reply-from plugin provides Paperless-ngx API proxying
  • Structured logging (pino) is built in

Negative

  • Smaller community than Express; fewer Stack Overflow answers
  • Plugin encapsulation model requires understanding scopes (can be confusing initially)
  • Some Express middleware is not directly compatible (must use Fastify equivalents)

Clone this wiki locally