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 runtscwithngtscenabled, 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 updatemigrations 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/compiler—ngtsccalls into the lower-level compiler for template parsing and IR generation. The boundary is well defined:compiler-cliknows about TypeScript,compilerdoes not.@angular/core— produced output references theɵ-prefixed runtime APIs.- Bazel
ng_modulerule — readsngtscoutput to populatedist/. - The Angular Language Service (
@angular/language-service) — embedsngtscto power editor diagnostics, completions, and hovers without re-running the full compiler.
Entry points for modification
- A new decorator annotation: add a handler under
packages/compiler-cli/src/ngtsc/annotations/. Implementanalyze,resolve, andcompile. - A new template type-check rule: extend
packages/compiler-cli/src/ngtsc/typecheck/. The TCB generator and the diagnostic mapper are the two files that always need to change together. - A new compiler flag: add it to
packages/compiler-cli/src/ngtsc/core/api/, thread it throughNgCompiler, and document it in thetsconfigschema generated for IDEs.
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.