skip to content

In an Angular CLI library project, why does the production build set `compilationMode` to `partial`, and what goes wrong if you publish a development build?

level: middleimportance: must knowfreq 45%

answer

  1. two tsconfig files, two configurations
  2. private Ivy instructions
  3. finished by the consuming app's build
  4. app version at least the library's

basics

~20 s

Partial compilation emits Angular code not tied to one Angular runtime version, and the consuming app's build finishes it. A development build uses full compilation, which only works with the exact Angular version it was built against.

solid answer

~40 s

The library schematic writes two TypeScript configs: `tsconfig.lib.json` for the `development` configuration and `tsconfig.lib.prod.json`, which adds `angularCompilerOptions.compilationMode: "partial"`, for `production`, the `defaultConfiguration`. Full compilation emits Ivy instructions that are private API and can change between patch releases, so a fully compiled library only works with the exact Angular version it was built with. Partial output is stable across versions and is completed by the application's build, which is why published libraries must use it. The rule on top: the app's Angular version must be the same as or newer than the one the library was built with; an older app is unsupported, and its build can fail with an error asking you to upgrade the app. Full mode is fine inside the workspace, where app and library share one Angular install.

code

json · 9 lines
json
{
  "extends": "./tsconfig.lib.json",
  "compilerOptions": {
    "declarationMap": false
  },
  "angularCompilerOptions": {
    "compilationMode": "partial"
  }
}

go deeper

for a junior

Recall that the default library build is production, which compiles in partial mode, and that you publish that output.

for a middle

Explain the two tsconfig files, why full Ivy output is version-locked, and why partial output is finished by the consuming app's build.

for a senior

Show release judgement: build with the lowest supported Angular, never publish a development build, and read a consumer's version error correctly.

for a principal

Weigh how the forward-only compatibility rule shapes a library's support policy and the order in which a fleet of apps upgrades.

## Two configurations, two compilation modes When `ng generate library ui-kit` runs, the Angular CLI writes two TypeScript configuration files for the new project and wires them to the `build` target's configurations in `angular.json`: | Configuration | tsconfig | Compilation mode | Use it for | |---|---|---|---| | `production` (the `defaultConfiguration`) | `tsconfig.lib.prod.json` | `partial` | anything you publish | | `development` | `tsconfig.lib.json` | full (the compiler's default) | local builds inside the workspace | `tsconfig.lib.prod.json` extends `tsconfig.lib.json` and adds two things: `declarationMap: false`, and in `angularCompilerOptions` the setting `"compilationMode": "partial"`. Because `production` is the default configuration, a plain `ng build ui-kit` already produces partial output; you have to ask for `--configuration development` to get a full build. ## What full compilation ties you to The Angular compiler turns decorators and templates into **Ivy instructions**: calls into private functions of `@angular/core`. In an application that is fine, because the compiler and the runtime ship together and are always the same version. The Angular documentation calls this the **full-Ivy** format and warns that it "contains private Angular Ivy instructions, which are not guaranteed to work across different versions of Angular", so it "requires that the library and application are built with the exact same version of Angular". Publish such a build and every consumer on a different patch release is exposed to instructions that may have been renamed, removed or changed in signature. ## What partial compilation buys you **Partial compilation** (the documentation's **partial-Ivy** format) emits a version-stable description of each component, directive, pipe and injectable instead of the private instructions. The consuming application's build completes that code with its own compiler, so the application and all its libraries end up on a single Angular version. The Angular CLI does this automatically; consumers need no extra configuration. What the partial output contains and how it is completed belongs to the compiler topic; for the CLI the facts that matter are: - partial output is the **publishing format** the Angular Package Format requires; - it is **portable forward**: a library built with an older Angular works in apps on the same or newer versions; - it is **not portable backward**: the documentation says the app's Angular version must be the same as or greater than the one used to build any of its libraries, and an older app is not supported. When the library's compiled declarations need a newer Angular than the app's compiler, the app build fails with an error saying the application depends on a library published with a newer Angular and asking you to upgrade the application. That last rule is why teams building a shared library compile it with the **lowest Angular version they support**, not the newest. ## What goes wrong in practice 1. **Publishing a development build.** Someone runs `ng build ui-kit --configuration development` to debug, then publishes `dist/ui-kit`. It works in the app that shares the same Angular version and breaks, or breaks later, in apps on other patches. The fix is to always publish the output of the default production build. 2. **Building the library with a newer Angular than its consumers.** The library's own workspace was upgraded first; apps still on the previous major are now unsupported and may fail at build time. Either keep the library's build toolchain at the lowest supported version, or release it as a major and let consumers upgrade. 3. **Setting partial mode on an application.** It has no effect: the application builder warns that partial compilation is not supported when building applications and uses full compilation instead. ## Why the workspace still defaults development to full Inside one workspace the app and the library share one `node_modules`, so the exact-version requirement is met automatically. The Angular CLI's own end-to-end suite consumes a workspace library built both ways, full and partial, in both AOT and JIT app builds. Full mode is therefore a legitimate local choice; it is only the **published artifact** that must be partial. ## Checklist before publishing - Build with the default configuration: `ng build ui-kit`. - Publish from the output folder: `cd dist/ui-kit && npm publish`, not from `projects/ui-kit`. - Build with the oldest Angular version your `peerDependencies` range admits.

  • Can you set `compilationMode: "partial"` in an application's tsconfig to speed up its build?
    No. The application builder does not support partial compilation for applications: it emits a warning and switches to full compilation. Partial mode exists so a library can be published without being tied to one Angular version; an application is always compiled fully, together with the partial code of its libraries.
  • A library built with Angular 22 is installed in an app on Angular 21; what happens?
    Angular does not support it: an app must be on the same or a newer Angular than its libraries were built with. If the library's compiled declarations need a newer Angular than the app's compiler, the build fails and tells you to upgrade the application; even if it happens to build, the pairing is unsupported. Building the library with the oldest supported Angular avoids forcing that upgrade on consumers.
  • When is a full-compilation library build acceptable?
    When the library is only consumed inside the same workspace, so the app and library always share one Angular install, as with the `development` configuration during local work. The Angular documentation describes full-Ivy as useful where all library and application code is built from source together.

Partial compilation is like shipping flat-pack furniture with instructions: each buyer assembles it with their own tools. A full build is furniture glued to fit one room; move it to another and it may not fit.

saying these in an interview costs you the question

  • Partial mode ships uncompiled TypeScript that the app compiles from scratch.
  • A full build is safe to publish because Ivy instructions are public API.
  • Build shared libraries with the newest Angular so every app benefits.
  • Partial compilation also speeds up application builds if you enable it there.
  • ng build for a library uses the development configuration unless told otherwise.