Skip to main content
@knitkit/node brings the same manifest-driven federation to your Node.js server. It installs module.register loader hooks so that bare specifiers you negotiate in an import map resolve to remote ESM modules fetched over HTTP — exactly the same modules the browser loads. Before executing any remote file, the loader verifies its sha384 integrity hash. After rendering, serializeImportMap emits a <script type="importmap"> tag with browser URLs so the client hydrates against the same dependency versions the server used — no dual-React, no hydration mismatch.

Install

How it works

registerFederation(importMap) calls Node’s built-in module.register to install a pair of loader hooks (resolve + load) on a worker thread. From that point forward, any import() call whose specifier appears in the map’s "imports" object resolves through the map — just like the browser does. Relative imports inside a remote module resolve against the remote’s own URL, so the remote’s full dependency graph loads over the network automatically. The import map you pass to registerFederation is typically the one produced by negotiateShared (re-exported from @knitkit/node), which means the server and browser negotiate from the same manifest and arrive at the same winner for every shared package.
Call registerFederation before importing any module that must resolve through the map. Node’s loader hooks take effect for imports made after the call returns; earlier imports are already resolved and cannot be redirected.

Step-by-step setup

SRI verification

Every remote module the loader fetches is checked against its sha384 integrity hash before Node evaluates it. The hash comes from the integrity field of the import map, keyed by the resolved URL (or the bare specifier). If the fetched content does not match, the loader throws with code KNIT_ERR_SRI_MISMATCH and refuses to execute the file.
knitkit build writes sha384 hashes for every expose into knit.manifest.json automatically, so you get SRI protection without any manual hashing.

Module cache

The loader hooks run on a Node worker thread and carry measurable per-import overhead. ModuleCache (exported from @knitkit/node) stores fetched and SRI-verified module source in memory keyed by resolved URL, so repeated SSR render paths pay the network and verification cost only once per process lifetime.
The hooks bundle their own internal ModuleCache instance automatically. Export your own instance only when you need to pre-warm, introspect, or selectively invalidate cache entries.

Full server entry example

The following is drawn from the examples/node-ssr example in the knitkit repo. It shows the complete flow: fetch manifest, install hooks, render with react-dom/server, serialize the import map, and return HTML.
renderToString is used here for simplicity. react-dom/server’s streaming APIs (renderToPipeableStream, renderToReadableStream) drop in the same way — registerFederation and serializeImportMap are rendering-strategy agnostic.

Programmatic vs. --import bootstrap

If you prefer not to call registerFederation in code, you can supply the import map via environment variable and use the --import flag:
@knitkit/node/register reads FEDKIT_IMPORT_MAP_JSON (inline JSON) or FEDKIT_IMPORT_MAP (a path to a JSON file) and calls registerFederation before your server entry runs. If neither variable is set, it emits a process warning and skips installation.