Express isn't exactly "old and bad" — it's more that NestJS solves problems that become painful at scale. Here's the real picture.
Express — The Problem at Scale
Express is a minimal, unopinionated framework. That's its strength and its weakness.
No structure enforced — every developer organizes code differently
No built-in DI (Dependency Injection) — you wire everything manually
No TypeScript-first design — TS works, but it's bolted on
No conventions — teams invent their own patterns, leading to inconsistency
Callback/middleware chaos — large apps become hard to trace and test
For small projects or microservices, Express is perfectly fine. But in a team of 5+ working on a large API? It starts to hurt.
NestJS — What It Fixes
NestJS is built on top of Express (or Fastify), but adds a full architectural layer inspired by Angular:
FeatureExpressNestJSStructureYou decideModules, Controllers, ServicesDependency InjectionManual / noneBuilt-in IoC containerTypeScriptOptionalFirst-classDecoratorsNoYes (@Controller, @Get, @Injectable)TestingDIY setupBuilt-in testing utilitiesMiddleware/Guards/PipesManualStandardized lifecycleWebSockets, gRPC, QueuesDIYBuilt-in supportOpenAPI/SwaggerManualAuto-generated from decorators
The Core Architectural Win — Modules & DI
ts
// NestJS — clean, testable, self-documenting
@Injectable()
export class UserService {
constructor(private readonly db: PrismaService) {}
async getUser(id: string) {
return this.db.user.findUnique({ where: { id } });
}
}
@Controller('users')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get(':id')
getUser(@Param('id') id: string) {
return this.userService.getUser(id);
}
}In Express, you'd manually import, instantiate, and pass dependencies everywhere. NestJS's IoC container handles all of that — making your code modular, swappable, and easily testable.
When to Still Use Express
Quick scripts or tiny APIs
You want full control and minimal abstraction
Very experienced team with strong conventions already in place
Ultra-lightweight microservices