Skip to main content

85. NestJS as Enterprise Backend Framework

Status: Accepted Date: 2025-07-06

Context

We need to choose a backend framework for building the Mercury application in TypeScript. While there are many options available (like Express, Fastify, or Koa), many of them are unopinionated libraries that require a lot of boilerplate and manual setup to create a well-structured, maintainable application suitable for a complex domain like a trading system. We need a framework that provides strong architectural guidance and out-of-the-box support for enterprise application patterns.

Decision

We will use NestJS as the primary backend framework for the Mercury system.

NestJS is a "batteries-included" framework that provides a highly structured, opinionated architecture based on concepts from Angular. We are choosing it for its core features:

  • Powerful Dependency Injection (DI): NestJS has a first-class DI container, making it easy to build loosely-coupled, testable components.
  • Modular Architecture: The framework is built around a strong module system, which is a perfect fit for our "Modular Monolith" architecture (adr://microservices-within-monolith).
  • TypeScript First: NestJS is written in and for TypeScript, providing a fantastic developer experience with strong typing and modern language features.
  • Rich Ecosystem: It has excellent integrations for common needs like database ORMs (MikroORM), queueing (BullMQ), configuration management, validation, and more.

Consequences

Positive:

  • High Productivity & Maintainability: The framework's structure and conventions guide developers towards writing clean, organized, and maintainable code, which increases productivity and reduces bugs.
  • Excellent Testability: The dependency injection system makes it trivial to mock dependencies in unit tests, leading to a highly testable codebase.
  • Scalable Architecture: The module system and clear separation of concerns allow the application to scale in complexity without becoming a "big ball of mud."
  • Strong Conventions: The opinionated nature of the framework ensures that all developers are following the same patterns, making the codebase consistent and easy to navigate.

Negative:

  • Learning Curve: NestJS is more complex and opinionated than simpler libraries like Express. It has a steeper learning curve, especially for developers not familiar with its concepts (like decorators, modules, and dependency injection).
  • "Magic" and Boilerplate: The heavy use of decorators and the underlying module system can sometimes feel like "magic," obscuring what's happening under the hood. It can also require a bit more boilerplate for simple applications compared to a micro-framework.

Mitigation:

  • Team Expertise: Our team has existing experience with NestJS and its architectural patterns, which significantly reduces the learning curve.
  • Value of Structure: For a complex, long-lived application, the initial learning curve and boilerplate are a small price to pay for the long-term benefits of a well-structured and maintainable codebase. The "magic" enables powerful features that would be difficult to build from scratch.
  • Clear Documentation: We will leverage NestJS's excellent official documentation and supplement it with our own project-specific guidelines and FDDs.