All posts
Angular Package Format
Angular

Angular Package Format

Angular Package Format (APF) is the official standard that makes Angular libraries "just work" for everyone—across different projects, build tools, and Angular versions.

IKIgor Katsuba
5 minutes read

Angular Package Format (APF): The Backbone of Angular Libraries

When building Angular libraries, you want your package to "just work" for everyone—across different projects, build tools, and Angular versions. The Angular Package Format (APF) is the official standard that makes this possible.


Why Does APF Exist?

Angular is more than a framework—it's an ecosystem. Libraries are everywhere: UI kits, utilities, data layers, and more. But not all npm packages are created equal! Without a standard, library consumers would face:

  • Build errors or warnings
  • Broken type definitions
  • Incompatibility with Angular CLI or Ivy
  • Tree-shaking issues (unused code in bundles)

APF solves these problems by defining how Angular libraries should be structured, built, and published.


A Brief History of APF

Angular libraries have evolved alongside the framework itself. Here's a quick timeline:

  • Angular 2–5: Early libraries shipped multiple formats (ES5, UMD, ESM) and special metadata for View Engine. No formal spec.
  • Angular 6 (2018): APF v6 introduced. ES modules by default, sideEffects: false for tree-shaking, and better CLI support.
  • Angular 8: TypeScript types are bundled per entry point. Deep imports discouraged.
  • Angular 10: tslib required as a dependency for helper functions.
  • Angular 13: Major simplification—no more View Engine, only Ivy. Legacy formats (CommonJS, UMD) removed. ES2020 is the new baseline.
  • Angular 16: Packages target ES2022. Even leaner, faster, and more future-proof.

Anatomy of an APF Package

A typical APF-compliant package looks like this:

my-angular-lib/
├── README.md
├── package.json
├── index.d.ts
├── fesm2022/
│   └── my-angular-lib.mjs
└── ...

Key elements:

  • package.json: The heart of your package. Includes special fields:
    • type: "module" (ESM by default)
    • sideEffects: false (enables tree-shaking)
    • exports (controls public entry points)
    • peerDependencies (e.g., @angular/core, tslib)
  • index.d.ts: Bundled TypeScript types for your public API.
  • fesm2022/: Flattened ES2022 module (main entry point for consumers).
  • Secondary entry points (optional): e.g., my-angular-lib/testing for test utilities or my-angular-lib/button for a button component.

Deep Dive: package.json Fields

A well-formed package.json is crucial for APF. Here are the most important fields:

{
  "name": "my-angular-lib",
  "type": "module",
  "sideEffects": false,
  "exports": {
    ".": {
      "types": "./index.d.ts",
      "esm2022": "./fesm2022/my-angular-lib.mjs"
    },
    "./testing": {
      "types": "./testing/index.d.ts",
      "esm2022": "./fesm2022/my-angular-lib-testing.mjs"
    }
  },
  "peerDependencies": {
    "@angular/core": ">=16.0.0",
    "tslib": ">=2.0.0"
  }
}
  • exports: Controls what consumers can import. Prevents deep imports into internal files.
  • sideEffects: false: Tells bundlers your code has no global side effects, enabling tree-shaking.
  • peerDependencies: Ensures consumers use compatible Angular and tslib versions.

How APF Enables Tree-Shaking

Tree-shaking is the process of removing unused code from your final bundle. APF helps by:

  • Using ES modules (static imports/exports)
  • Marking the package as sideEffects: false
  • Bundling all public APIs in a single entry point

This means consumers only get the code they actually use—no more, no less.


Building an APF-Compliant Library

The easiest way is to use Angular CLI and ng-packagr (or Nx):

ng generate library my-lib
ng build my-lib

The both tools will generate an APF-compliant package and we already did it in the previous lesson.

Secondary Entry Points

Large libraries often split features into sub-packages (e.g., @angular/material/button). APF supports this via secondary entry points:

  • Each entry point gets its own folder, package.json, and type definitions.
  • The main exports field in the root package.json maps these entry points.

Example:

"exports": {
  ".": { ... },
  "./button": {
    "types": "./button/index.d.ts",
    "esm2022": "./fesm2022/my-angular-lib-button.mjs"
  }
}

This lets consumers import only what they need:

import { MyButtonComponent } from 'my-angular-lib/button';

We will use secondary entry points in the next lesson!


Common Pitfalls & Best Practices

  • Don't use deep imports (e.g., my-lib/esm2022/foo). Always import from the public API.
  • Keep dependencies up to date: Especially tslib and Angular peer dependencies.
  • Test your package: Try installing it in a fresh Angular project before publishing.
  • Document your entry points: Make it clear in your README how to import features.

And allways use the ng-packagr to build your library! It will generate an APF-compliant package for you. ng-packagr is the only tool that fully supports APF!


The Future of APF

APF evolves with Angular. As the framework targets newer JavaScript versions and build tools, APF will continue to simplify and modernize. Staying up to date with Angular CLI and its generators is the best way to ensure your library remains compatible.


More Than Just APF: What ng-packagr Brings to the Table

While ng-packagr's main job is to implement the Angular Package Format (APF), it also provides a rich set of features that make building and publishing Angular libraries much easier and more robust.

Here's a quick overview of what it offers out of the box:

Packaging & Compatibility
  • 🎁 Implements Angular Package Format
  • 🏁 Produces optimized FESM2022 bundles
  • 🧳 Packages are ready for Angular CLI, Webpack, and ESM bundlers
  • 💃 Generates TypeScript definitions (.d.ts)
  • 🔎 Supports both scoped and non-scoped npm packages
Assets & Styles
  • 🏄 Inlines component templates and stylesheets
  • ✨ Advanced CSS support:
    • 🐫 SCSS preprocessing with custom include paths
    • 🐒 Automatic vendor prefixing
    • 🐯 Embeds asset data directly into your bundle

Read also


🎁 Pre-order now — "Angular UI Kit"

We’re launching our first interactive course on ng.guide, where you'll build a production-grade UI library using real-world Angular practices.

  • Fully interactive lessons
  • Real components and examples
  • One-click Stackblitz integration

💸 Early-bird price: $99 (was $125) — available only before launch.

Reserve your access now and get hands-on with how Angular works at scale.