DEV Community

Cover image for How to Use NestJS as SSR Server for Angular v20 | POC
Kerschbaumer Stefan
Kerschbaumer Stefan

Posted on

How to Use NestJS as SSR Server for Angular v20 | POC

Did you ever think about using nestjs as your SSR Server for angular v20 ?
It's actually pretty easy to set this up as a POC.

First of all we need to install a few dependencies to our angular application.

Those are:
`

"@nestjs/serve-static": "^5.0.3",
"@nestjs/cli": "^11.0.7",
"@nestjs/common": "^11.1.5",
"@nestjs/core": "^11.1.5",
"@nestjs/platform-express": "^11.1.5",
"@nestjs/schematics": "^11.0.5",
"@types/node": "^20.19.8",
"reflect-metadata": "^0.2.2",
Enter fullscreen mode Exit fullscreen mode

`

After that we need to define a middleware to use the AngularNodeAppEngine within our NestJS server.

After that we need to create our AppModule where we register the Middleware and import the ServerStaticModule for static content serving.

This will look like this:

That's basically all we need.
Our server.ts within the Angular App will look like this:

Now if you run npm run start and have SSR enabled you will see that the NestJS server starts up perfectly fine.

Please note that this is just a simple POC and needs some tweaking as for example sometimes when the app is reloading the server is not shutting down completly or npm run build doesn't work at this time.

But i will try to improve my POC github repo to fix this issues.

You can find the minimal POC repo here:
https://github.com/xsip/ng-nest-ssr

Hopefully this helped you in some way.
Have a nice day :)

Top comments (2)

Collapse
 
alexcibotari profile image
Alex Cibotari • Edited

Hello,

This article will help you resolve the issue with reloading the server: stackoverflow.com/questions/793153...

I still was not able to resolve the issue with

npm run build
Enter fullscreen mode Exit fullscreen mode
Collapse
 
kyleryanbanks profile image
Kyle Banks

The UI does seem to work with this solution, but as of Oct. 2025, esbuild has compatibility issues with NestJs's legacy typescript decorator usage that breaks dependency injection in the NestJs application.

If you update the controller to inject a service in the POC repo, you can see the following error message when your try to access the service at runtime.

@Controller('api')
export class AppController {
  constructor(public appService: AppService) {}

  @Get()
  root(): string {
    return this.appService.getHello();
  }
}
Enter fullscreen mode Exit fullscreen mode

[Nest] 60186 - 10/14/2025, 1:12:45 AM ERROR [ExceptionsHandler] TypeError: Cannot read properties of undefined (reading 'getHello')

It's possible to use explicit injection tokens so that NestJs doesn't have to use the decorator metadata, but it does add some extra work for every DI and provider usage.

// in module
  providers: [{ provide: 'SERVICE', useClass: AppService }],

// in some NestJs call (controller/service/etc)
  constructor(@Inject('SERVICE') public appService: AppService) {}
Enter fullscreen mode Exit fullscreen mode

Adding esbuild plugins to do some pre-compilation of TS code can also solve this, in theory, but I haven't been able to generate a working example yet. The default angular application builder does not accept plugins, but custom builders, such as @angular-builders/custom-esbuild, or Nx's @nx/angular:application builder do allow for custom plugins to be provided inserted before the angular esbuild compilation happens.

Possible Plugin Solutions
npmjs.com/package/esbuild-decorators
github.com/thomaschaaf/esbuild-plu...

Separately, in the POC repo, the build fails due to external dependencies in NestJS. You can fix that by update the esbuild options to include 'externalDepencies'. This will silently ignore attempts to import those libraries. If you are actually using any of these libraries, you would not exclude it here and make sure that the library is included as a dependency in your package.json.

"build": {
   "builder": "@angular/build:application",
      "options": {
         "externalDependencies": [
              "@grpc/proto-loader",
              "@grpc/grpc-js",
              "@nestjs/websockets",
              "@nestjs/microservices",
              "cache-manager",
              "kafkajs",
              "mqtt",
              "nats",
              "ioredis",
              "amqplib",
              "amqp-connection-manager",
              "@fastify/static",
              "class-validator",
              "class-transformer"
        ],
Enter fullscreen mode Exit fullscreen mode

Similar NestJS SSR host example
github.com/OysteinAmundsen/home

Oystein Amundsen has done some similar work but has a lot of extra custom complexity that is making it hard for me to understand why he doesn't have the DI issue when it looks like the API code in his repository is only ever built by esbuild.