Skip to main content

ADR-003: Use NestJS

Status

Accepted

Date

2026-07-20

Context

Chilarai requires a backend platform capable of supporting:

  • Multi-tenant SaaS architecture
  • School administration
  • Student lifecycle management
  • Admissions workflows
  • Attendance management
  • Fee management
  • Reporting services
  • Integrations
  • Future AI-assisted workflows

The backend framework must provide:

  • Strong TypeScript support
  • Maintainable architecture
  • Rapid development velocity
  • Support for long-term platform growth
  • Compatibility with the selected frontend framework and monorepo architecture

A backend framework decision must be made before implementation of platform services begins.

Decision Drivers

The selected approach should:

  • Support TypeScript as a first-class citizen
  • Encourage maintainable architecture
  • Scale from startup to enterprise workloads
  • Support modular development
  • Provide good testability
  • Work well with Nx
  • Minimize architectural boilerplate
  • Support modern API development practices
  • Enable onboarding of future developers

Alternatives Considered

Option 1: Express.js

Advantages

  • Minimal framework
  • Large ecosystem
  • Mature and widely adopted
  • Flexible and lightweight

Disadvantages

  • Lacks architectural guidance
  • Requires substantial framework decisions
  • Easy to create inconsistent codebases
  • Dependency injection is not built in
  • Larger maintenance burden as the application grows

Assessment

Express is a strong foundation but requires significant engineering discipline to maintain consistency as the application grows.


Option 2: Fastify

Advantages

  • High performance
  • Lightweight architecture
  • Modern ecosystem
  • Good TypeScript support

Disadvantages

  • Less opinionated structure
  • Smaller ecosystem compared to Express
  • Requires additional architectural decisions

Assessment

Fastify is technically strong but does not provide enough architectural guidance for the long-term needs of the platform.


Option 3: ASP.NET Core

Advantages

  • Excellent performance
  • Strong enterprise maturity
  • Excellent dependency injection
  • Strong tooling
  • Good architectural patterns

Disadvantages

  • Requires adoption of C#
  • Reduced alignment with the chosen TypeScript frontend ecosystem
  • Shared contracts become more difficult
  • Increased context switching between frontend and backend development

Assessment

ASP.NET Core is an excellent enterprise framework but introduces unnecessary language diversity for a small team.


Option 4: NestJS

Advantages

  • TypeScript-first framework
  • Modular architecture
  • Built-in dependency injection
  • Strong testing support
  • Familiar patterns for enterprise development
  • Excellent integration with Node.js ecosystem
  • Strong Nx compatibility
  • Shared language across frontend and backend

Disadvantages

  • Additional abstraction over Express and Fastify
  • Requires understanding NestJS conventions
  • Slightly higher learning curve than Express

Assessment

NestJS provides strong architectural guidance while preserving access to the broader Node.js ecosystem.

Decision

Use NestJS as the primary backend application framework.

The backend implementation will use:

  • TypeScript
  • NestJS
  • Dependency Injection
  • Modular architecture
  • REST APIs initially
  • PostgreSQL for persistence
  • Shared contracts from shared-types
  • Shared validation from shared-validation

Rationale

NestJS provides the best balance between startup productivity and long-term maintainability.

The platform benefits significantly from:

  • Modular application structure
  • Built-in dependency injection
  • Consistent architectural patterns
  • Shared TypeScript language across frontend and backend
  • Strong testability
  • Excellent Nx integration

Compared with Express or Fastify, NestJS reduces the number of architectural decisions that must be made by developers and encourages consistency from the beginning.

Compared with ASP.NET Core, NestJS maintains a single-language TypeScript ecosystem across the entire platform.

The framework aligns with the team's existing expertise and the long-term platform goals.

Consequences

Positive Consequences

  • Consistent backend architecture
  • Strong developer productivity
  • Reduced architectural inconsistency
  • Improved testability
  • Shared language across frontend and backend
  • Easier onboarding of contributors
  • Strong support for long-term growth

Negative Consequences

  • Developers must learn NestJS conventions
  • Additional abstraction layer over Node.js frameworks
  • Some framework-specific concepts become part of the architecture

Follow-up Actions

  • Adopt a module-based architecture
  • Separate domain, application, and infrastructure concerns where appropriate
  • Establish API design guidelines
  • Standardize validation through shared schemas
  • Establish testing standards for services and controllers