This document describes how to build server-rendered MVC (Model-View-Controller) applications with NestJS using template engines. Unlike typical REST APIs that return JSON responses, MVC applications render HTML views on the server and serve complete web pages to clients. This pattern is suitable for traditional web applications, server-side rendering scenarios, and applications that require SEO-friendly content delivery.
For REST API development, see HTTP Request Processing. For serving static assets alongside APIs, see Static File Serving. For platform adapter details, see Express Integration and Fastify Integration.
Sources: sample/15-mvc/package.json1-52 sample/17-mvc-fastify/package.json1-54
NestJS supports the MVC pattern by extending its HTTP adapter layer to integrate with template engines. Controllers return view names and data objects instead of JSON responses, and the platform adapter renders templates with the provided data before sending HTML to the client.
Sources: sample/15-mvc/package.json21-28 sample/17-mvc-fastify/package.json21-30
NestJS provides MVC support through both Express and Fastify platform adapters. Each platform requires specific configuration and packages for template engine integration.
The Express adapter (@nestjs/platform-express) integrates with Express-compatible template engines through the native Express view engine API. The 15-mvc sample demonstrates this configuration.
Key Dependencies:
@nestjs/platform-express - Express HTTP adapterhbs - Handlebars template engine for Express.hbs extensionThe Fastify adapter (@nestjs/platform-fastify) uses the @fastify/view plugin for template rendering and @fastify/static for static file serving. The 17-mvc-fastify sample demonstrates this configuration.
Key Dependencies:
@nestjs/platform-fastify - Fastify HTTP adapter@fastify/view - View rendering plugin@fastify/static - Static file serving pluginhandlebars - Handlebars engine (used with @fastify/view)Sources: sample/15-mvc/package.json21-28 sample/17-mvc-fastify/package.json21-30
For Express applications, the template engine is configured using the adapter's setViewEngine() and setBaseViewsDir() methods during application initialization.
Configuration Pattern:
The Express adapter supports multiple template engines:
For Fastify applications, template configuration requires registering the @fastify/view plugin with the underlying Fastify instance, along with @fastify/static for serving assets.
Configuration Pattern:
Sources: sample/15-mvc/package.json25 sample/17-mvc-fastify/package.json25-27
NestJS provides the @Render() decorator for declarative view rendering. The decorator specifies the template name, and the method returns the data object to pass to the template.
Usage Pattern:
Alternatively, controllers can access the platform-specific response object and call its render() method directly. This provides more control over the rendering process.
Usage Pattern:
Sources: sample/15-mvc/package.json22-24 sample/17-mvc-fastify/package.json22-24
MVC applications follow a specific directory structure to organize views, static assets, and server-side code.
Directory Layout:
src/ - TypeScript application code (controllers, services, modules)views/ - Template files (.hbs, .ejs, .pug)public/ - Static assets (CSS, JavaScript, images)dist/ - Compiled JavaScript outputSources: sample/15-mvc/package.json7-13 sample/17-mvc-fastify/package.json7-13
MVC applications serve static assets (CSS, JavaScript, images) alongside rendered views. Both platform adapters provide methods for configuring static file serving.
The Express adapter uses the useStaticAssets() method, which internally calls express.static().
Configuration:
The Fastify adapter requires registering the @fastify/static plugin with a URL prefix.
Configuration:
Sources: sample/15-mvc/package.json21-28 sample/17-mvc-fastify/package.json25
The NestJS repository includes two MVC sample applications demonstrating different platform implementations.
Located at sample/15-mvc/, this sample demonstrates MVC pattern implementation using Express with Handlebars (hbs).
| Configuration | Value |
|---|---|
| Platform | @nestjs/platform-express (11.1.13) |
| Template Engine | hbs (4.2.0) |
| Dependencies | @nestjs/core, @nestjs/common, reflect-metadata, rxjs |
| Scripts | start, start:dev, start:debug, start:prod, build, test |
Key Features:
Located at sample/17-mvc-fastify/, this sample demonstrates MVC pattern implementation using Fastify with Handlebars through @fastify/view.
| Configuration | Value |
|---|---|
| Platform | @nestjs/platform-fastify (11.1.13) |
| View Plugin | @fastify/view (11.1.1) |
| Static Plugin | @fastify/static (9.0.0) |
| Template Engine | handlebars (4.7.8) |
| Dependencies | @nestjs/core, @nestjs/common, reflect-metadata, rxjs |
Key Features:
Sources: sample/15-mvc/package.json1-52 sample/17-mvc-fastify/package.json1-54
Comparison Table:
| Aspect | Express MVC | Fastify MVC |
|---|---|---|
| HTTP Adapter | @nestjs/platform-express | @nestjs/platform-fastify |
| View Rendering | Native Express views API | @fastify/view plugin |
| Static Files | useStaticAssets() → express.static() | @fastify/static plugin |
| Template Engine Package | hbs (Handlebars for Express) | handlebars (standalone) |
| Configuration Style | Adapter methods | Plugin registration |
| Performance | Standard | Higher throughput |
| Ecosystem | Mature Express middleware | Fastify plugin ecosystem |
Sources: sample/15-mvc/package.json21-28 sample/17-mvc-fastify/package.json21-30
Both MVC samples share identical development scripts and workflows:
Build Process:
Development Server:
Production:
Code Quality:
Sources: sample/15-mvc/package.json6-19 sample/17-mvc-fastify/package.json6-19
MVC applications can integrate with other NestJS features while maintaining the server-rendered architecture.
The request pipeline (Guards → Interceptors → Pipes → Controller) works identically for MVC routes. Guards can protect view routes, and interceptors can modify view data before rendering.
MVC controllers can inject database services (TypeORM, Sequelize, Mongoose, Prisma) to fetch data for view rendering, similar to REST API controllers. See Database Integrations.
MVC applications can implement session-based authentication using Passport strategies, with guards protecting view routes. See Authentication and Authorization.
MVC applications can serve WebSocket gateways alongside rendered views, enabling real-time features in server-rendered applications. See WebSocket Support.
Sources: sample/15-mvc/package.json21-28 sample/17-mvc-fastify/package.json21-30
The Express adapter supports any template engine compatible with Express's view system:
| Engine | Package | Extension | Description |
|---|---|---|---|
| Handlebars | hbs | .hbs | Logic-less templates, used in sample/15-mvc |
| EJS | ejs | .ejs | Embedded JavaScript |
| Pug | pug | .pug | Indentation-based syntax (formerly Jade) |
| Nunjucks | nunjucks | .njk | Jinja2-inspired templating |
| Mustache | mustache | .mustache | Minimalist templating |
The Fastify adapter supports engines compatible with @fastify/view:
| Engine | Package | Configuration | Description |
|---|---|---|---|
| Handlebars | handlebars | engine.handlebars | Used in sample/17-mvc-fastify |
| EJS | ejs | engine.ejs | Embedded JavaScript |
| Pug | pug | engine.pug | Indentation-based syntax |
| Nunjucks | nunjucks | engine.nunjucks | Jinja2-inspired templating |
| Liquid | liquidjs | engine.liquid | Shopify-style templating |
Sources: sample/15-mvc/package.json25 sample/17-mvc-fastify/package.json26
MVC applications use the same testing infrastructure as REST APIs, with additional considerations for view rendering.
Test Configuration:
Test Types:
Sources: sample/15-mvc/package.json15-18 sample/17-mvc-fastify/package.json15-18
Both MVC samples produce identical build artifacts using the NestJS CLI:
Build Process:
nest build (uses @nestjs/cli 11.0.16)dist/ directoryviews/, public/)node dist/mainRuntime Requirements:
dist/views/ directory with templatespublic/ directory with static assetsSources: sample/15-mvc/package.json7-13 sample/17-mvc-fastify/package.json7-13
Refresh this wiki