Skip to main content
A knitkit manifest (knit.manifest.json) is the JSON contract that a federated remote publishes for host applications to consume. It declares which modules the remote exposes for dynamic loading, which packages the remote shares (along with the exact versions and accepted ranges), and the URLs of the prebundled ESM assets for each. Host applications fetch manifests at boot, run version negotiation across all remotes, and emit a single native import map — the manifest is the data that drives every step of that process. The current spec version is "0.1", and it is locked for Phase 1.

Top-level shape


exposes object

The exposes map declares the modules this remote makes available for dynamic loading by host applications.

Key format

Expose keys must start with ./ (e.g. "./CartWidget", "./utils/format"). This mirrors the ES module subpath convention and makes keys unambiguous relative paths. When calling loadRemote, you may omit the ./ prefix — loadRemote("checkout/CartWidget") and loadRemote("checkout/./CartWidget") resolve to the same module.

ExposeDecl fields


shared object

The shared map declares the packages this remote contributes to cross-remote version negotiation. For each entry, knitkit selects a single winning version (or a scoped fallback for non-singletons) and maps the bare package name to its ESM URL in the import map.

SharedDecl fields

Semver range syntax

The requiredVersion field supports the following range forms:

Singleton semantics

  • singleton: true (default) — the runtime expects every host and remote to share exactly one instance. If no version satisfies every participant’s requiredVersion, negotiation throws KNIT_ERR_SINGLETON_CONFLICT. Use this for packages like React that break when multiple instances exist in one page.
  • singleton: false — a participant whose required range cannot be satisfied by the negotiated winner is silently given its own copy via an import map scopes entry, so it loads its own version rather than sharing the winner’s. The winner is still used by all compatible participants.

URL resolution

All relative URL values — both exposes[].url and shared[].url — are resolved against the manifest’s own URL using the standard new URL(ref, manifestBaseUrl).toString() algorithm. When registerRemotes fetches a manifest over HTTP, it uses the resolved response URL (after any redirects) as the base, so relative paths are always correct regardless of whether you passed a relative request path. For inline manifests (where you pass a Manifest object directly rather than a URL string), relative URLs are left as-is and resolved from an empty base — use absolute URLs in inline manifests.

Full example

The following is a complete, valid knit.manifest.json produced by knitkit build and knitkit types generate for a React-based checkout micro-frontend:

Versioning

The spec field pins the manifest document to a specific revision of this specification. Changes to the spec follow these rules: The runtime in @knitkit/runtime uses a strict equality check against the spec field (m.spec !== "0.1"), so a manifest with a future spec version will fail validation until the runtime is updated to accept it. Always keep the @knitkit/runtime and @knitkit/cli packages at matching versions to avoid spec skew.

Validation

@knitkit/runtime exports validateManifest(input, sourceLabel) — the authoritative validator for this spec. It is the same function used by registerRemotes at runtime and by knitkit validate on the command line. It throws a FedkitError with code KNIT_ERR_MANIFEST_INVALID and a precise .message plus an actionable .suggestion on any validation failure. See the Runtime API reference for full details.