skip to content

With the Angular CLI, what does `ng generate component` create in a v22 project, and how do you preview it before any file is written?

level: juniorimportance: must knowfreq 72%

answer

  1. a schematic, not a file copier
  2. @schematics/angular:component
  3. folder, .ts, .html, .css, .spec.ts
  4. no .component suffix, no changeDetection line
  5. --dry-run prints CREATE lines only

basics

~10 s

ng generate component user-card runs the @schematics/angular:component schematic, which creates a user-card/ folder with user-card.ts, .html, .css and .spec.ts for a standalone UserCard class; --dry-run (-d) lists those files without writing them.

solid answer

~40 s

`ng generate` (alias `ng g`) runs a schematic; `component` (alias `c`) resolves to `@schematics/angular:component`. In a v22 workspace created with the default 2025 file-name style, `ng g c user-card` from the workspace root creates `src/app/user-card/` holding `user-card.ts`, `user-card.html`, `user-card.css` and `user-card.spec.ts`. The class is `UserCard`, the selector gets the project prefix (`app-user-card`), and the decorator has `imports: []` but no `standalone` flag and no `changeDetection` line, because standalone and `OnPush` are already the framework defaults. Options shape the output: `--inline-template` (`-t`), `--inline-style` (`-s`), `--skip-tests`, `--flat`, `--style scss`, `--change-detection Eager`. Adding `--dry-run` (`-d`) prints the `CREATE` lines and a note that no changes were made.

code

bash · 3 lines
bash
ng g c user-card --dry-run
ng g c features/orders/order-list --skip-tests --style scss
ng g c banner -t -s --change-detection Eager

go deeper

for a junior

Know the command and aliases (ng g c), the four files it creates and the flags for inline template, inline style, skipping tests and dry run.

for a middle

Explain that generators are schematics whose schema.json defines flags and defaults, and why v22 output omits standalone and changeDetection.

for a senior

Use dry runs and generator options to keep a large team's output consistent, and know how version changes (2025 file names, OnPush default, @Service) show up in generated code.

for a principal

Treat generators as a governance lever: decide which conventions are enforced by generator defaults rather than by review comments, and plan for defaults that shift across majors.

## What `ng generate` actually runs `ng generate` (alias `ng g`) does not copy fixed files. It runs a **schematic**: a small program that takes options, describes file changes against an in-memory copy of the workspace, and only then writes them. When you type `ng generate component user-card`, the CLI looks up `component` in the workspace's schematic collections. By default that is the `@schematics/angular` collection, where `component` has the alias `c`. So `ng g c user-card` and `ng generate @schematics/angular:component user-card` do the same thing. Each schematic has a `schema.json`. Its properties become the command's flags, their `default` values become the defaults, and `x-prompt` entries become interactive questions when you leave a required value out. ## What a v22 component generation produces Run from the workspace root of an application created with Angular CLI 22 defaults, `ng g c user-card` creates: - `src/app/user-card/user-card.ts`: the component class - `src/app/user-card/user-card.html`: the template (`templateUrl`) - `src/app/user-card/user-card.css`: the stylesheet (`styleUrl`) - `src/app/user-card/user-card.spec.ts`: a unit test The generated decorator is short, on purpose: 1. **No `standalone: true`.** Standalone is the framework default since v19, and the schematic's `standalone` option defaults to `true`. With `--standalone false` it writes `standalone: false` and declares the class in the closest NgModule. 2. **No `changeDetection` line.** Since v22 a component without `changeDetection` is `OnPush`, and the schematic's `changeDetection` option defaults to `OnPush`. It only writes `ChangeDetectionStrategy.Eager` when you pass `--change-detection Eager`. 3. **An empty `imports: []`** for the standalone component's template dependencies. 4. **A prefixed selector** such as `app-user-card`, taken from the project's `prefix` unless you pass `--prefix`. The file and class names follow the **2025 style guide**, the default since v20: the file is `user-card.ts` (not `user-card.component.ts`) and the class is `UserCard` (not `UserCardComponent`). A workspace created with `--file-name-style-guide 2016` gets `type`-suffix defaults written into `angular.json` instead. ## The options you reach for most | Flag | Effect | |---|---| | `--inline-template` / `-t` | Template inside the `.ts` file, no `.html` | | `--inline-style` / `-s` | Styles inside the `.ts` file, no stylesheet | | `--style scss` | Stylesheet type: `css`, `scss`, `sass`, `less` or `none` | | `--skip-tests` | No `.spec.ts` | | `--flat` | Files go directly into the target folder, with no folder of their own | | `--change-detection Eager` | Writes the old always-check strategy explicitly | | `--type container` | File `user-card.container.ts`; class gets `Container` appended | | `--project admin` | Targets another project in a multi-project workspace | A name with slashes such as `ng g c features/orders/order-list` puts the folder under `src/app/features/orders/`. Other generators follow the same model. `ng g s cart` creates a flat `cart.ts` service, which in v22 uses the `@Service()` decorator, or `@Injectable({ providedIn: 'root' })` with `--injectable`. `ng g guard`, `ng g pipe`, `ng g directive` and the rest are listed by `ng generate --help`. ## Previewing with `--dry-run` `--dry-run` (alias `-d`) runs the schematic completely against the in-memory tree, then stops before anything touches the disk. The CLI prints one line per planned change, for example `CREATE src/app/user-card/user-card.ts (...bytes)` or `UPDATE src/app/app.module.ts`. It ends with `NOTE: The "--dry-run" option means no changes were made.` Follow-up tasks a schematic schedules, such as a package install, are skipped too. That makes it the safe way to: - check where files will land before generating into a shared folder; - see which existing files, such as an NgModule, a schematic would edit; - try an unfamiliar third-party generator. If a file the schematic wants to create already exists with different content, the run fails with an error instead of writing half the files. The virtual tree is applied to disk all at once or not at all. ## Prompts and non-interactive runs When a required option is missing, the schematic's `x-prompt` asks for it: `ng g c` with no name asks what to call the component. Three shared flags control this: - `--interactive=false` turns every prompt off, which is what scripts and CI want; - `--defaults` skips prompts for options that already have a default, and still asks for the rest; - `--force` is described by the CLI as forcing the overwriting of existing files. Typing the value on the command line, as in `ng g c user-card`, avoids the prompt in the first place. ## Why this is worth knowing in an interview Generators are the team's cheapest way to stay consistent. Everyone gets the same file layout, naming and test stub, and the defaults move with the framework: new components have been `OnPush` since v22 without anyone editing a template. A candidate who knows that `ng generate` is a schematic with a schema can explain where the flags come from. They can also explain how to change the defaults and why a dry run is trustworthy.

  • Why does the generated v22 component have no `changeDetection` property?
    Since v22 a component that omits `changeDetection` is `OnPush`, and the component schematic's `changeDetection` option defaults to `OnPush`. The template only writes the property for the other value: `--change-detection Eager` adds `ChangeDetectionStrategy.Eager`, the old always-check behaviour.
  • What does `ng g s cart` generate in a v22 workspace, and how do you get the older decorator?
    It creates a flat `cart.ts`, with no folder because `flat` defaults to true for services. The class is decorated with `@Service()`, which makes it auto-provided. Passing `--injectable` generates `@Injectable({ providedIn: 'root' })` instead, which is the form most existing codebases use.
  • How do you find every generator and flag available in a workspace?
    Run `ng generate --help` for the schematics the configured collections provide, and `ng generate component --help` for one schematic's options. The flags come from that schematic's `schema.json`, so a third-party collection's generators and options show up the same way.

saying these in an interview costs you the question

  • Thinks ng generate copies fixed template files with no options or logic
  • Expects user-card.component.ts and UserCardComponent from a fresh v22 project
  • Believes a component without changeDetection still defaults to the always-check strategy in v22
  • Says --dry-run writes the files and then prints a diff
  • Adds standalone: true by hand because the generator 'forgot' it