> For AI agents: the complete documentation index is available at https://rspack.rs/llms.txt, the full documentation bundle is available at https://rspack.rs/llms-full.txt.

# NestJS

Rspack can build [NestJS](https://nestjs.com/) applications. Compared with `tsc`, Rspack can bundle application code, transform TypeScript with SWC, enable development HMR, and leave runtime dependencies external when needed.

## How to use

Start with the common [Node.js application configuration](https://rspack.rs/guide/integrations/node.md), then add the NestJS settings described below. You can also use the [NestJS example](https://github.com/rstackjs/rstack-examples/tree/main/rspack/nestjs) in `rstack-examples` as a reference. It includes a complete `rspack.config.mjs`, development script, production build script, and HMR entry.

## Example

The [rstack-examples](https://github.com/rstackjs/rstack-examples/tree/main/rspack/nestjs) repository contains a complete NestJS application built with Rspack.

## Install dependencies

Install the common Node.js build dependencies from the [Node.js guide](https://rspack.rs/guide/integrations/node.md#install-dependencies), then install the NestJS runtime packages:


```sh [npm]
npm add @nestjs/common @nestjs/core @nestjs/platform-express reflect-metadata rxjs
```

```sh [yarn]
yarn add @nestjs/common @nestjs/core @nestjs/platform-express reflect-metadata rxjs
```

```sh [pnpm]
pnpm add @nestjs/common @nestjs/core @nestjs/platform-express reflect-metadata rxjs
```

```sh [bun]
bun add @nestjs/common @nestjs/core @nestjs/platform-express reflect-metadata rxjs
```

```sh [deno]
deno add npm:@nestjs/common npm:@nestjs/core npm:@nestjs/platform-express npm:reflect-metadata npm:rxjs
```

## Basic concepts

NestJS applications run in Node.js, so most configurations can follow the common [Node.js configuration](https://rspack.rs/guide/integrations/node.md). The main NestJS-specific requirement is decorator metadata, which NestJS uses at runtime.

- **Decorator metadata**: Enable TypeScript decorators and emitted metadata so dependency injection, controllers, routes, guards, interceptors, and other NestJS features work correctly.
- **HMR cleanup**: When development HMR updates the server bundle, close the previous Nest application instance before accepting the update.
- **Production minification**: Keep class and function names stable because NestJS may use them through metadata reflection and execution context APIs.

## Configure Rspack

The following configuration is adapted from the NestJS example. It combines the common Node.js setup with the decorator metadata options required by NestJS:

```js title="rspack.config.mjs"
// @ts-check
import { defineConfig } from '@rspack/cli';
import { rspack } from '@rspack/core';
import { RunScriptWebpackPlugin } from 'run-script-webpack-plugin';
import nodeExternals from 'webpack-node-externals';

export default defineConfig({
  context: import.meta.dirname,
  target: 'node',
  entry: {
    main:
      process.env.NODE_ENV === 'production'
        ? './src/main.ts'
        : ['@rspack/core/hot/poll?100', './src/main.ts'],
  },
  output: {
    clean: true,
  },
  resolve: {
    extensions: ['...', '.ts', '.tsx', '.jsx'],
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: {
          loader: 'builtin:swc-loader',
          options: {
            detectSyntax: 'auto',
            jsc: {
              parser: {
                decorators: true,
              },
              transform: {
                legacyDecorator: true,
                decoratorMetadata: true,
              },
            },
          },
        },
      },
    ],
  },
  optimization: {
    minimizer: [
      new rspack.SwcJsMinimizerRspackPlugin({
        minimizerOptions: {
          compress: {
            keep_classnames: true,
            keep_fnames: true,
          },
          mangle: {
            keep_classnames: true,
            keep_fnames: true,
          },
        },
      }),
    ],
  },
  plugins: [
    process.env.NODE_ENV !== 'production' &&
      new RunScriptWebpackPlugin({
        name: 'main.js',
        autoRestart: false,
      }),
  ],
  devServer: {
    devMiddleware: {
      writeToDisk: true,
    },
  },
  externals: [
    nodeExternals({
      allowlist: [/@rspack\/core\/hot\/poll/],
    }),
  ],
});
```

## Configure scripts

Use `rspack dev` during development and `rspack build` for production:

```json title="package.json"
{
  "scripts": {
    "build": "rspack build",
    "dev": "rspack dev",
    "start": "node dist/main.js"
  }
}
```

- `dev`: Runs Rspack Dev Server, writes the server bundle to disk, and starts `dist/main.js`.
- `build`: Creates a production bundle without the HMR polling entry.
- `start`: Runs the production bundle with Node.js.

## Configure TypeScript decorators

NestJS uses decorators such as `@Module()`, `@Controller()`, `@Injectable()`, and `@Get()`. Configure `builtin:swc-loader` so SWC can parse these decorators and emit the metadata NestJS needs:

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: {
          loader: 'builtin:swc-loader',
          options: {
            detectSyntax: 'auto',
            jsc: {
              parser: {
                decorators: true,
              },
              transform: {
                legacyDecorator: true,
                decoratorMetadata: true,
              },
            },
          },
        },
      },
    ],
  },
};
```

If your project also runs `tsc`, keep `experimentalDecorators` and `emitDecoratorMetadata` enabled in `tsconfig.json` so TypeScript and Rspack use the same decorator assumptions:

```json title="tsconfig.json"
{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}
```

## Configure development HMR

Add `@rspack/core/hot/poll` only in development. If it is included in the production bundle, the Node.js application will fail at runtime because HMR is not available in build mode:

```js title="rspack.config.mjs"
export default {
  entry: {
    main:
      process.env.NODE_ENV === 'production'
        ? './src/main.ts'
        : ['@rspack/core/hot/poll?100', './src/main.ts'],
  },
};
```

Add HMR handling to the NestJS bootstrap file. This closes the old application instance before accepting the updated module:

```ts title="src/main.ts"
declare const module: any;

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}

bootstrap();
```

See [Node.js - Configure development HMR](https://rspack.rs/guide/integrations/node.md#configure-development-hmr) for the shared Rspack entry, `writeToDisk`, `RunScriptWebpackPlugin`, and externals allowlist settings used with this bootstrap code. If your project needs ESM output, see [Node.js - Use ESM output](https://rspack.rs/guide/integrations/node.md#use-esm-output).

## Configure production minification

When minifying a NestJS server bundle, keep class names and function names. NestJS can rely on stable class and handler references through metadata reflection and execution context APIs.

```js title="rspack.config.mjs"
import { rspack } from '@rspack/core';

export default {
  optimization: {
    minimizer: [
      new rspack.SwcJsMinimizerRspackPlugin({
        minimizerOptions: {
          compress: {
            keep_classnames: true,
            keep_fnames: true,
          },
          mangle: {
            keep_classnames: true,
            keep_fnames: true,
          },
        },
      }),
    ],
  },
};
```

## Native node modules

If a NestJS dependency includes a Node.js native addon (`.node` module), follow [Node.js - Native node modules](https://rspack.rs/guide/integrations/node.md#native-node-modules) to emit the addon with `asset/resource` and let Node.js load it at runtime.
