Open-Source Wikis

/

Angular

/

Packages

/

@angular/compiler-cli

angular/angular

@angular/compiler-cli

ngtsc — Angular's TypeScript transformer plugin — and ngc, the binary that drives it. Also home to the partial-compilation linker, the template type checker, and the schematics infrastructure used by other packages.

Purpose

@angular/compiler-cli runs as a thin shell around tsc. It plugs annotation handlers into the TypeScript program so that decorated classes get compiled to Ivy, and it generates type-check blocks so template binding errors surface as ordinary TypeScript diagnostics.

Three top-level surfaces:

  • ngtsc — the TypeScript plugin. The CLI build, Bazel build, and angular.dev's build all run tsc with ngtsc enabled, so this is the production compile path.
  • linker — finishes "partial" Ivy compilation in libraries shipped on npm. Runs as a Babel plugin in the consumer's bundler.
  • Schematics infrastructure — the test harness and runtime helpers used by ng update migrations across all packages.

Directory layout

packages/compiler-cli/
├── src/
│   ├── main.ts                # The ngc binary entry point
│   ├── extract_i18n.ts        # i18n extraction CLI
│   ├── perform_compile.ts     # tsc + ngtsc invocation
│   ├── perform_watch.ts       # Watch mode driver
│   ├── ngtsc/                 # The transformer
│   │   ├── annotations/       # ComponentDecoratorHandler, ...
│   │   ├── core/              # Top-level NgCompiler orchestration
│   │   ├── transform/         # tsc transform plumbing
│   │   ├── typecheck/         # Template type checking (TCB generation)
│   │   ├── scope/             # Module / standalone scope resolution
│   │   ├── partial_evaluator/ # Static-evaluation engine for decorator args
│   │   ├── reflection/        # ts.Symbol → Angular-shaped metadata
│   │   ├── imports/           # Import emission with alias awareness
│   │   ├── incremental/       # Incremental compile cache
│   │   ├── shims/             # Generated shim files (.ngtypecheck.ts, etc.)
│   │   ├── perf/              # Compilation performance instrumentation
│   │   ├── resource/          # templateUrl/styleUrls loader
│   │   ├── docs/              # API doc extraction (used by adev)
│   │   └── ...
│   └── transformers/          # tsc transformer integration
├── linker/                    # Partial → full Ivy linker (Babel plugin)
└── test/

Key abstractions

Type / function File What it is
NgtscProgram packages/compiler-cli/src/ngtsc/program.ts The top-level program that wraps ts.Program and drives all annotation handlers.
NgCompiler packages/compiler-cli/src/ngtsc/core/ Owns analysis/resolution/compile state across phases.
ComponentDecoratorHandler packages/compiler-cli/src/ngtsc/annotations/component Recognizes @Component, resolves templates and styles, calls into @angular/compiler.
DirectiveDecoratorHandler annotations/directive/ Same for @Directive.
NgModuleDecoratorHandler, PipeDecoratorHandler, InjectableDecoratorHandler annotations/ Handlers for the remaining decorators.
TypeCheckBlockTransformer packages/compiler-cli/src/ngtsc/typecheck/ Generates type-check blocks (TCBs) from templates.
PartialEvaluator packages/compiler-cli/src/ngtsc/partial_evaluator Statically evaluates decorator argument expressions.
IncrementalCompilation packages/compiler-cli/src/ngtsc/incremental/ Cache that keeps watch-mode compiles fast.
LinkerPlugin (Babel) packages/compiler-cli/linker/babel/ Babel plugin that links partial Ivy code to full Ivy.
main() packages/compiler-cli/src/main.ts The ngc CLI entry point.

How ngtsc runs

graph TD
  Tsc["tsc(...) with ngtsc plugin"] --> NgtscProgram[NgtscProgram]
  NgtscProgram --> Detect["Detect decorators<br/>(annotations/*)"]
  Detect --> Analyze[".analyze(): per-class metadata"]
  Analyze --> Resolve[".resolve(): cross-class linking<br/>(scopes, references)"]
  Resolve --> Typecheck["typecheck/: generate TCBs"]
  Typecheck --> Diagnostics["TS diagnostics from TCBs"]
  Resolve --> Compile[".compile(): emit Ivy IR"]
  Compile --> Translator["transform/: TS source-text patches"]
  Translator --> Emit[".js + .d.ts files"]
  NgtscProgram --> Incremental["incremental/ caches across runs"]

The Analyze / Resolve / Compile phases are explicit: a decorator is analyzed first to collect raw information, then resolved (which may require cross-file lookups), then compiled (which produces the actual Ivy output).

Type checking

The typecheck/ subtree generates synthetic TypeScript for each template. For a binding like <button (click)="save(item)"> it emits something like:

function _tcb1(this: MyComponent) {
  // ...synthetic statements that mirror the binding semantics...
  this.save(item);
}

Errors detected by tsc on the generated code are remapped back to template offsets, producing diagnostics that look like template errors. The remapping logic lives in typecheck/src/diagnostics.ts and the surrounding files.

strictTemplates (and its sub-flags like strictInputTypes, strictOutputEventTypes) toggle how strict the generated TCBs are. The TCB generator is one of the most performance-sensitive parts of the compiler.

Partial compilation and the linker

Library packages on npm are pre-compiled to "partial" Ivy form via compilationMode: "partial". The output is structurally similar to full Ivy but version-stable: the ɵfac and ɵcmp factories take a small number of well-defined arguments and pass through opaque IR.

The Babel-based linker (packages/compiler-cli/linker/) runs in the consumer's bundler and converts the partial output to whatever full Ivy form the consumer's framework version expects. This is what lets a library compiled against v15 run on v17 without a re-publish.

Incremental compilation

The incremental/ subtree implements tsc-style incremental compilation across ngtsc's analysis/resolution/compile phases. It's necessary for watch builds (pnpm ng build --watch, pnpm adev) to feel instant after the first compile.

Schematics support

@angular/compiler-cli exposes utilities used by other packages' schematics:

  • AST manipulation helpers tuned for Angular metadata.
  • Migration test scaffolding that integrates with the workspace schematics runner.

The actual ng update migrations live in each package (packages/core/schematics/, packages/router/schematics/, etc.).

Integration points

  • @angular/compilerngtsc calls into the lower-level compiler for template parsing and IR generation. The boundary is well defined: compiler-cli knows about TypeScript, compiler does not.
  • @angular/core — produced output references the ɵ-prefixed runtime APIs.
  • Bazel ng_module rule — reads ngtsc output to populate dist/.
  • The Angular Language Service (@angular/language-service) — embeds ngtsc to power editor diagnostics, completions, and hovers without re-running the full compiler.

Entry points for modification

For the deeper architecture, the reference-compiler-cli project skill walks through the mental model in detail. Open it via the Skill tool when working in this package.

See also: systems/template-compiler for the cross-package compile pipeline.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

@angular/compiler-cli – Angular wiki | Factory