Skip to content
NestJS ns getting-started 4 min read

Nest CLI Deep Dive

The Nest CLI (@nestjs/cli) is the command-line companion that scaffolds, builds, and runs your NestJS applications. Instead of hand-writing boilerplate for every module, controller, and service, you delegate that work to schematics that produce consistent, idiomatic code and wire it into the dependency-injection graph for you. Mastering the CLI dramatically speeds up day-to-day development and keeps a large codebase uniform across teams.

Installing the CLI

The CLI is typically installed globally so the nest command is available everywhere, though projects also pin it as a dev dependency for reproducible builds.

npm install -g @nestjs/cli
nest --version

Output:

11.0.5

You can verify the available commands at any time with nest --help, and inspect a specific command with nest generate --help.

Generating code with schematics

The nest generate command (aliased as nest g) runs schematics — code generators that create files and update surrounding code. The general form is nest g <schematic> <name>. Each schematic has a short alias to save keystrokes.

SchematicAliasGenerates
modulemoA @Module class and registers it in the parent module
controllercoA @Controller with a spec file
servicesAn @Injectable provider
resourceresA full CRUD resource (module, controller, service, DTOs, entity)
guardguA CanActivate guard
pipepiA transformation/validation pipe
interceptoritcA NestInterceptor

For example, generating a users service nests it under a users directory and creates the corresponding test file:

nest g service users

Output:

CREATE src/users/users.service.ts (89 bytes)
CREATE src/users/users.service.spec.ts (453 bytes)

The generated provider is a ready-to-use injectable class:

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {}

When you generate a controller in the same module, the CLI automatically declares it in the surrounding @Module, so you rarely edit module metadata by hand:

import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
  controllers: [UsersController],
  providers: [UsersService],
})
export class UsersModule {}

Scaffolding a full CRUD resource

The resource schematic is the biggest time-saver: it prompts for a transport layer (REST, GraphQL, microservice, or WebSockets) and emits a complete, working CRUD slice including DTOs.

nest g resource products

Output:

? What transport layer do you use? REST API
? Would you like to generate CRUD entry points? Yes
CREATE src/products/products.controller.ts (957 bytes)
CREATE src/products/products.service.ts (625 bytes)
CREATE src/products/products.module.ts (267 bytes)
CREATE src/products/dto/create-product.dto.ts (33 bytes)
CREATE src/products/dto/update-product.dto.ts (181 bytes)
CREATE src/products/entities/product.entity.ts (24 bytes)

Useful generation flags

Two flags come up constantly. Use --dry-run (-d) to preview changes without touching disk, and --no-spec to skip test files.

nest g controller orders --no-spec --dry-run

Tip: Run nest g resource <name> --dry-run before committing to a transport layer. The preview shows every file that would be created so you can confirm the structure before generating it for real.

Building and running the application

The CLI wraps the TypeScript compiler (and optionally webpack) so you do not invoke tsc directly.

CommandPurpose
nest buildCompile to the dist/ directory for production
nest startCompile and run the app once
nest start --watchRecompile and restart on file changes
nest start --debug --watchWatch mode with the Node inspector attached

During development, watch mode is the default workflow:

nest start --watch

Output:

[Nest] 4821  - 06/14/2026, 9:12:03 AM     LOG [NestFactory] Starting Nest application...
[Nest] 4821  - 06/14/2026, 9:12:03 AM     LOG [InstanceLoader] AppModule dependencies initialized
[Nest] 4821  - 06/14/2026, 9:12:03 AM     LOG [NestApplication] Nest application successfully started

For production, nest build compiles ahead of time and you start the plain Node process from the emitted JavaScript:

nest build
node dist/main.js

Configuring nest-cli.json

The nest-cli.json file at the project root controls how the CLI compiles and bundles your app. The most important settings live under compilerOptions.

{
  "$schema": "https://json.schemastore.org/nest-cli",
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "deleteOutDir": true,
    "webpack": false,
    "assets": [
      "**/*.graphql",
      { "include": "config/*.yaml", "outDir": "dist/config", "watchAssets": true }
    ]
  }
}
OptionEffect
deleteOutDirWipes dist/ before each build to avoid stale artifacts
webpackSwitches the build from tsc to webpack (enables HMR)
assetsCopies non-TypeScript files (templates, .graphql, config) into the output
watchAssetsRe-copies matched assets when they change in watch mode
sourceRootThe directory schematics treat as the source root

The assets array is essential because the TypeScript compiler only emits .js files — any .hbs, .graphql, or .yaml files your app reads at runtime must be copied explicitly, otherwise they go missing in dist/.

Warning: Enabling "webpack": true changes how the build behaves and is required for Hot Module Replacement, but it can mask issues with dynamic require calls. Stick with the default tsc build unless you specifically need HMR.

Best Practices

  • Install the CLI as a dev dependency in addition to globally so CI builds use the exact pinned version.
  • Prefer nest g resource for new feature slices to get consistent DTOs and CRUD wiring out of the box.
  • Always preview destructive or large generations with --dry-run before writing files.
  • Enable deleteOutDir to prevent stale compiled files from leaking into production builds.
  • Declare every runtime non-TS file in assets so templates and schemas ship in dist/.
  • Use nest start --debug --watch while debugging so you can attach the inspector without restarting manually.
Last updated June 14, 2026
Was this helpful?