Problem Statement

Modern Node.js backends suffer from:

  • OpenAPI drifting away from real behavior
  • repetitive, meaningless controllers
  • lack of input/output validation
  • weak architectural boundaries
  • logging and instrumentation added as an afterthought

These issues slow teams down and create false confidence.

Solution

I built an opinionated backend framework that:

  • enforces architectural discipline by default
  • removes boilerplate from controllers
  • guarantees API correctness at startup
  • treats observability and transactions as first-class concerns

The goal was speed through constraints, not flexibility.

Custom DSL for route definitions

Routes are created using a custom DSL system and are validated before the server even starts to avoid bugs. This happens to be very similar to what Fastify does.

Routes are generated, as well as OpenAPI spec is generated from the actual specs, and not handwritten.

Auto Input and Output Validation

Inputs and Outputs both are validated at runtime to avoid schema drift and ensure services receive the current input.

Input and Output validation eliminates runtime surprises and prevents undocumented behavior.

Thin controllers by Design

Controllers mostly convert the HTTP domain to service domain. Hence, they are intentionally made thin or non-existent to simply extract the required values from request and set output in response.

Context-bound Execution

  • context available only at service boundaries
  • prevents implicit global state leaks

Strict Transaction Enforcement

All database queries must be part of a Transaction. This is enforced via a service boundary and context management. An added side-effect of this is that it allows adding Row-Level Security (RLS) very trivial.

Query Builder instead of ORMs

To avoid leaky abstractions, and greater SQL control, Query builder is used instead of an ORM.

Structured JSON logging & auto instrumentation

  • Structured JSON logging provided by default
  • intent-based tracking built-in
  • Service is auto instrumented with execution time
  • Logging automatically happens after service completes execution

Usage and Impact

  • Designed for reuse across multiple backend projects
  • Significantly reduced:
    • setup time
    • duplicated logic
    • API drift
  • Still evolving toward a CLI-driven framework experience

Future Plans

  • Package as a formal framework with CLI scaffolding
  • Improve ergonomics without weakening constraints
  • Add first-class support for background jobs and workflows
  • Have TypeScript support by default