| name | api-reports |
| description | Manage API Extractor reports and release tag entry points in the Fluid Framework monorepo. Use when regenerating API reports, adding new exports, changing release tags, or debugging API Extractor errors. Triggers on mentions of API reports, api-extractor, release tags, entry points, public/beta/alpha/legacy/internal exports. |
API Report Management
Manage the API Extractor and release tag system in the Fluid Framework monorepo.
Overview
Every published package has:
- Entry point files (
public.d.ts, beta.d.ts, alpha.d.ts, legacy.d.ts) generated by flub generate entrypoints
- API report files (
.api.md) generated by api-extractor run that snapshot the public API surface
- Lint configs that validate entry points are well-formed and release tags are consistent
The two-phase system works as follows:
- Phase 1:
flub generate entrypoints reads src/index.ts, filters by release tags, and writes filtered .d.ts files into lib/ and dist/
- Phase 2:
api-extractor run reads those .d.ts files and produces .api.md report snapshots
Release Tags
Apply these TSDoc tags to exported symbols in source code:
| Tag | Visibility | Included In |
|---|
@public | Stable, supported | public.d.ts, beta.d.ts, alpha.d.ts |
@beta | Under development | beta.d.ts, alpha.d.ts |
@alpha | Experimental | alpha.d.ts only |
@legacy | Deprecated but maintained | legacy.d.ts |
@internal | Not for external use | index.d.ts (internal entry point) only |
@sealed | Cannot be extended/implemented | (modifier, used with above tags) |
@system | Internal system types | Shown in reports for context |
New APIs should typically start at @alpha or @beta, not @public.
Entry Points in package.json
The exports field maps subpaths to filtered type definitions:
{
"exports": {
".": { "import": { "types": "./lib/public.d.ts", "default": "./lib/index.js" } },
"./beta": { "import": { "types": "./lib/beta.d.ts", "default": "./lib/index.js" } },
"./alpha": { "import": { "types": "./lib/alpha.d.ts", "default": "./lib/index.js" } },
"./legacy": { "import": { "types": "./lib/legacy.d.ts", "default": "./lib/index.js" } },
"./internal": { "import": { "types": "./lib/index.d.ts", "default": "./lib/index.js" } }
}
}
Each path also has a require variant pointing to dist/ for CJS. The JS entry point is always index.js — only the type definitions differ per release level.
Not all packages expose all levels. Most expose . (public), ./internal, and ./legacy. Only packages with beta/alpha APIs add those paths.
Source File Organization
src/index.ts — all exports (public + beta + alpha + internal)
src/alpha.ts — if needed, re-exports from index.ts with alpha-level filtering (rare, most packages just use tags)
src/legacy.ts — legacy exports (older API surface)
src/internal.ts — re-exports everything from index.ts (used by ./internal path)
Regenerating API Reports
After Changing Exports in a Package
cd packages/path/to/package
fluid-build . --task compile
npm run api-extractor:esnext
npm run api-extractor:commonjs
npm run build:api-reports
Or use the single command:
fluid-build . --task api
Verify Entry Points Are Valid
npm run check:exports
This runs all lint configs (api-extractor-lint-public.esm.json, etc.) to validate each entry point.
API Report Files
Located in api-report/ within each package:
| File | Content |
|---|
<pkg>.public.api.md | Public API snapshot |
<pkg>.beta.api.md | Public + beta API snapshot |
<pkg>.alpha.api.md | Public + beta + alpha API snapshot |
<pkg>.legacy.public.api.md | Legacy public API |
<pkg>.legacy.beta.api.md | Legacy public + beta API |
These files are committed to the repo. Changes to them in a PR indicate the public API surface has changed.
Reading Report Diffs
When .api.md files change in a PR:
- Added lines = new APIs being exposed
- Removed lines = APIs being removed (potential breaking change)
- Changed signatures = API modification (check backward compatibility)
API Extractor Config Hierarchy
Each package has an api-extractor/ directory with configs that extend base configs:
common/build/build-common/
├── api-extractor-base.json # Root: rules, error levels
├── api-extractor-base.esm.json # ESM: enables reports + doc model
├── api-extractor-report-base.esm.json # Reports: bundled packages, suppressions
├── api-extractor-report.esm.current.json # Current: public+beta variants (default)
├── api-extractor-report.esm.legacy.json # Legacy: legacy entry point
├── api-extractor-lint.entrypoint.json # Lint: validate single entry point
└── api-extractor-lint.json # Lint: cross-package tag validation
Package-level configs extend these:
packages/dds/tree/api-extractor/
├── api-extractor.current.json # extends report.esm.current
├── api-extractor.legacy.json # extends report.esm.legacy
├── api-extractor-lint-public.esm.json # extends lint.entrypoint
├── api-extractor-lint-public.cjs.json # extends lint.entrypoint (CJS)
├── api-extractor-lint-beta.esm.json # extends lint.entrypoint
├── api-extractor-lint-alpha.esm.json # extends lint.entrypoint
├── api-extractor-lint-legacy.esm.json # extends lint.entrypoint
├── api-extractor-lint-legacy.cjs.json # extends lint.entrypoint
└── api-extractor-lint-bundle.json # extends lint (cross-package)
Default Report Variants
api-extractor-report.esm.current.json generates ["public", "beta"] by default
- Packages needing alpha reports override
reportVariants to ["public", "beta", "alpha"]
- Legacy configs always use the
legacy.d.ts entry point
Common API Extractor Errors
| Error Code | Meaning | Fix |
|---|
ae-missing-release-tag | Export has no release tag | Add @public, @beta, @alpha, or @internal |
ae-forgotten-export | Exported API references non-exported type | Export the referenced type or mark it @internal |
ae-incompatible-release-tags | Type uses a less-visible release tag | Promote the dependency or demote the consumer |
ae-extra-release-tag | Multiple release tags on one symbol | Use exactly one release tag per doc comment |
Adding a New Export
- Add the symbol to the appropriate source file
- Export it from
src/index.ts (or the appropriate entry module)
- Add a TSDoc comment with the correct release tag
- Rebuild:
fluid-build . --task api
- Verify the
.api.md report diff shows only the intended change
- Run
npm run check:exports to validate
Promoting an API (e.g., alpha to beta)
- Change the release tag in the source code (e.g.,
@alpha to @beta)
- Rebuild:
fluid-build . --task api
- Verify the symbol moves between report files (disappears from
alpha.api.md additions, appears in beta.api.md)
- Create a changeset describing the promotion
Bundled Packages
API Extractor bundles types from these scopes into the consuming package's reports:
@fluidframework/*
@fluid-internal/*
@fluid-experimental/*
@fluid-private/*
@fluid-tools/*
This means types from internal packages are inlined into the public API surface rather than appearing as external references.