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
TherequiredVersion 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’srequiredVersion, negotiation throwsKNIT_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 mapscopesentry, 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 — bothexposes[].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, validknit.manifest.json produced by knitkit build and knitkit types generate for a React-based checkout micro-frontend:
Versioning
Thespec 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.