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