> ## Documentation Index
> Fetch the complete documentation index at: https://knitkit.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Started with knitkit: Build a Remote and Load It

> Install knitkit, build a remote, load it from a host page, and type loadRemote() — from zero to working federation in under 10 minutes.

This guide walks you through the complete path from a blank project to a working federated app: install the packages, configure and build a remote, load it from a host page, and set up TypeScript types so `loadRemote` is fully typed. No bundler plugin is required at any step.

<Steps>
  <Step title="Install packages">
    Install the runtime as a regular dependency and the CLI as a dev dependency. Add optional packages only as you need them.

    <CodeGroup>
      ```bash npm theme={null}
      npm install @knitkit/runtime
      npm install --save-dev @knitkit/cli

      # Optional — add as your use case grows:
      npm install @knitkit/node        # Node SSR
      npm install @knitkit/react       # <RemoteComponent>
      npm install --save-dev @knitkit/overrides  # local-override dev widget
      ```

      ```bash yarn theme={null}
      yarn add @knitkit/runtime
      yarn add --dev @knitkit/cli

      # Optional:
      yarn add @knitkit/node
      yarn add @knitkit/react
      yarn add --dev @knitkit/overrides
      ```

      ```bash pnpm theme={null}
      pnpm add @knitkit/runtime
      pnpm add --save-dev @knitkit/cli

      # Optional:
      pnpm add @knitkit/node
      pnpm add @knitkit/react
      pnpm add --save-dev @knitkit/overrides
      ```
    </CodeGroup>
  </Step>

  <Step title="Create knit.config.json for the remote">
    In your remote application's root directory, create a `knit.config.json` file. The `name` field becomes the prefix consumers use in `loadRemote`. The `shared` array lists packages that should resolve to a single instance across the host and all remotes. The `exposes` array lists the entry points this remote makes available.

    ```json knit.config.json theme={null}
    {
      "name": "checkout",
      "shared": ["react", "react-dom"],
      "exposes": ["./CartWidget.tsx", "./CheckoutForm.tsx"]
    }
    ```

    <Note>
      The `name` field must be lowercase and match the pattern `[a-z][a-z0-9_-]*`. It is used as the prefix in `loadRemote("checkout/CartWidget")` — the host uses this exact string to address your remote.
    </Note>
  </Step>

  <Step title="Build the remote">
    Run the knitkit build command from your remote's root directory. The CLI bundles each shared dependency from `node_modules` into an individual ESM file, bundles each exposed entry point, and writes a manifest with SRI integrity hashes.

    ```bash theme={null}
    knitkit build
    ```

    The output lands in `dist/` with this structure:

    ```
    dist/
    ├── shared/
    │   ├── react-18.3.1.js          # prebundled ESM, one file per shared dep
    │   └── react-dom-18.3.1.js
    ├── exposes/
    │   ├── CartWidget.js            # bundled expose entry points
    │   └── CheckoutForm.js
    └── knit.manifest.json           # all URLs + SRI hashes — this is what the host fetches
    ```

    Serve the `dist/` directory from any static host, CDN, or local dev server. All URLs in the manifest are relative to the manifest's own URL, so the remote is portable across environments without rebuilding.

    To generate TypeScript declarations alongside the manifest, run:

    ```bash theme={null}
    knitkit types generate
    ```

    This emits `dist/types/*.d.ts` and records each types URL inside the manifest so `knitkit types sync` on the host side can download them automatically.
  </Step>

  <Step title="Load the remote from a host">
    The one hard rule when loading remotes in the browser: **inject the import map before the first module import that resolves through it.** Use a small bootstrap script at the top of your HTML to register remotes and inject the map, then dynamically import the rest of your application.

    ```html index.html theme={null}
    <!-- 1. Seed the import map with the runtime itself and any host-owned shared deps. -->
    <script type="importmap">
      {
        "imports": {
          "@knitkit/runtime": "/runtime/index.js",
          "react": "https://esm.sh/react@18.3.1",
          "react-dom": "https://esm.sh/react-dom@18.3.1"
        }
      }
    </script>

    <!-- 2. Bootstrap: register remotes, negotiate shared deps, inject the final map. -->
    <script type="module">
      import { registerRemotes, loadRemote } from "@knitkit/runtime";

      await registerRemotes(
        [{ name: "checkout", manifest: "https://cdn.example.com/checkout/knit.manifest.json" }],
        {
          hostShared: {
            react: { version: "18.3.1", requiredVersion: "^18.0.0", singleton: true, url: "https://esm.sh/react@18.3.1" },
            "react-dom": { version: "18.3.1", requiredVersion: "^18.0.0", singleton: true, url: "https://esm.sh/react-dom@18.3.1" }
          }
        }
      );

      // 3. Now load the rest of the app — the import map is fully in place.
      await import("/src/main.js");
    </script>
    ```

    After bootstrapping, call `loadRemote` anywhere in your application code:

    ```ts src/main.ts theme={null}
    import { loadRemote } from "@knitkit/runtime";

    // Returns the module's default export (or the full namespace if no default).
    const CartWidget = await loadRemote("checkout/CartWidget");
    CartWidget.mount(document.getElementById("cart-slot"));
    ```

    If you are using React, use `<RemoteComponent>` from `@knitkit/react` instead. It handles lazy loading, Suspense, and error boundaries automatically.

    ```tsx src/App.tsx theme={null}
    import { RemoteComponent } from "@knitkit/react";

    export function App() {
      return (
        <RemoteComponent
          name="checkout/CartWidget"
          fallback={<div>Loading cart…</div>}
          sku="ABC-123"
        />
      );
    }
    ```
  </Step>

  <Step title="Type your remotes">
    Create a `knit.host.json` file in the host project's root. This tells the CLI which remote manifests to fetch types from and where to write the downloaded declarations.

    ```json knit.host.json theme={null}
    {
      "remotes": [
        { "name": "checkout", "manifest": "https://cdn.example.com/checkout/knit.manifest.json" }
      ],
      "typesDir": ".knitkit/types"
    }
    ```

    Run the sync command to download each remote's `.d.ts` files and generate a module augmentation that makes `loadRemote` fully typed:

    ```bash theme={null}
    knitkit types sync
    ```

    Finally, add the types directory to your `tsconfig.json` so TypeScript picks up the augmentations:

    ```json tsconfig.json theme={null}
    {
      "compilerOptions": { "strict": true },
      "include": ["src", ".knitkit/types"]
    }
    ```

    After syncing, `loadRemote("checkout/CartWidget")` returns the exact type of that component's default export — full autocomplete and type checking, no manual declarations needed.
  </Step>
</Steps>

<Tip>
  Ready to go deeper? Check out the [browser host guide](/guides/browser-host) for a full walkthrough including CSP headers and SRI enforcement, the [Node SSR guide](/guides/node-ssr) for server-side rendering, and the [React integration guide](/guides/react-integration) for advanced `<RemoteComponent>` patterns.
</Tip>
