Skip to content

Runtime and services

NestJS

A structured Node framework with modules and dependency injection; it holds the ten domain modules of the Starterflare backend.

NestJS is an opinionated application framework for Node. It supplies modules, a dependency injection container, decorators for controllers and providers, pipes for validation, guards for authorisation, and adapters that let the same service speak HTTP, WebSockets or a message transport. The point of all that machinery is that a team stops making arbitrary decisions: there is one place a service goes, one way it receives its dependencies, and one shape a new module takes.

How we use it

Starterflare is the build. It is a modular monolith of ten backend domains, identity, profile, social, content, feed, messaging, jobs, notification, search and admin, running NestJS 11 with Prisma over PostgreSQL 16, Redis for caching and rate limiting, NATS JetStream for events between modules, OpenSearch for full text search, and Passport for OAuth and one time codes. Tracing and metrics are wired through OpenTelemetry and Prometheus, and it deploys with Docker Compose locally and Kubernetes manifests including autoscaling and ingress.

It also never launched, and the reason is instructive rather than embarrassing. The schema is over nine hundred lines and about forty-five models, the application source is roughly six and a half thousand lines, and the front end has eleven pages and two shared components. The framework made it easy to grow structure faster than product, and structure has to be maintained whether or not anybody is using it.

What it costs you

It needs a process that stays up, which means a host billed by the hour, and the design that comes naturally with it needs a database, a cache, a broker and a search cluster, none of which can be switched off without losing data or an index. That bill arrives at zero users. We worked the numbers rather than argued about them in what a Postgres, Redis, broker and search stack costs at rest, and it is the single best reason to think hard before starting here.

Dependency injection moves a class of errors from compile time to boot time, and stack traces route through the container rather than through your code, so a missing provider is a paragraph of framework internals rather than a line number. The boilerplate ratio is poor for small services: a three endpoint API is a controller, a service, a module, a set of data transfer objects and a test file, where the same thing elsewhere is one file. And major version upgrades move the framework, its platform adapter and a dozen decorator packages together, so they are a planned afternoon rather than a dependency bump.

It also does not run on an edge runtime. If a project starts here, that decision is effectively permanent.

When we would choose something else

For an API of moderate size where we control the conventions, Hono on Workers gives us the same routing and middleware with none of the standing cost, and that is what most of our own products use. Where a team already writes PHP, Laravel provides the same batteries with a shallower learning curve for the people who will maintain it. We would keep NestJS where the requirement is genuinely long-running: persistent connections, streaming, in-process schedulers, or heavy processor work that an edge runtime would refuse, and in that case it belongs on Kubernetes with the operational budget that implies.

Where we have used it

Every build below lists this in its stack, so the claim is checkable.