> ## 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.

# Typing loadRemote() with knitkit Types Sync

> Generate and sync TypeScript declarations for your remote modules so loadRemote() is fully typed, with auto-complete and type safety.

knitkit provides end-to-end TypeScript coverage through two CLI commands: `knitkit types
generate` (run on the **remote**) and `knitkit types sync` (run on the **host**). Together
they produce a `declare module "@knitkit/runtime"` block that augments the `RemoteModules`
interface, so `loadRemote("checkout/CartWidget")` resolves to the exact type that the
`checkout` remote's `CartWidget` module exports — no manual type stubs required.

***

## On the remote

Run these steps once after each build, or wire them into your remote's CI pipeline.

<Steps>
  <Step title="Build first, then generate types">
    Run your normal build, then immediately run the types command. `knitkit types generate`
    reads `dist/knit.manifest.json` and uses your project's locally installed `typescript`
    compiler to emit declaration files.

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

    <Note>
      `typescript` is an optional peer dependency of the CLI. If it is not installed in your
      project, the command throws with an actionable message: `npm i -D typescript`.
    </Note>

    The command writes one `.d.ts` file per exposed module into `dist/types/`:

    ```
    dist/
    ├── knit.manifest.json   ← patched in-place
    ├── types/
    │   ├── CartWidget.d.ts
    │   └── CheckoutButton.d.ts
    └── ...
    ```
  </Step>

  <Step title="Verify the manifest carries types paths">
    After running `knitkit types generate`, the manifest's `exposes` entries now include a
    `"types"` field pointing at each generated declaration:

    ```json theme={null}
    {
      "name": "checkout",
      "exposes": {
        "./CartWidget": {
          "url": "./CartWidget.js",
          "types": "./types/CartWidget.d.ts"
        },
        "./CheckoutButton": {
          "url": "./CheckoutButton.js",
          "types": "./types/CheckoutButton.d.ts"
        }
      }
    }
    ```

    The host's `knitkit types sync` command reads this `"types"` field to know what to
    download.
  </Step>
</Steps>

***

## On the host

Run these steps whenever a remote's types change, or schedule them as part of your CI
pre-build step.

<Steps>
  <Step title="Create knit.host.json">
    Add a `knit.host.json` file at your project root. List every remote your host consumes and
    configure the output directory for downloaded declarations:

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

    `"typesDir"` defaults to `".knitkit/types"` if omitted.
  </Step>

  <Step title="Run knitkit types sync">
    ```bash theme={null}
    knitkit types sync
    ```

    The command:

    1. Fetches each remote manifest listed in `knit.host.json`
    2. For every expose that has a `"types"` field, downloads the `.d.ts` file into
       `<typesDir>/<remoteName>/<exposeKey>.d.ts`
    3. Generates `<typesDir>/knitkit-remotes.d.ts` — a module augmentation that wires
       every remote specifier to its downloaded declaration type

    The result looks like this on disk:

    ```
    .knitkit/
    └── types/
        ├── checkout/
        │   ├── CartWidget.d.ts
        │   └── CheckoutButton.d.ts
        ├── profile/
        │   └── NavMenu.d.ts
        └── knitkit-remotes.d.ts   ← the augmentation file
    ```
  </Step>

  <Step title="Add the types directory to tsconfig.json">
    TypeScript needs to see the generated directory. Add it to the `include` array in your
    `tsconfig.json`:

    ```json theme={null}
    {
      "compilerOptions": { ... },
      "include": [
        "src",
        ".knitkit/types"
      ]
    }
    ```
  </Step>

  <Step title="Enjoy fully typed loadRemote() calls">
    With the augmentation in place, `loadRemote` resolves to the exact type the remote exports:

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

    // Typed as the default export of checkout's CartWidget module
    const CartWidget = await loadRemote("checkout/CartWidget");

    // TypeScript now knows CartWidget's props, including required ones
    // Typos in the specifier ("checkout/CartWIdget") are caught at compile time
    ```
  </Step>
</Steps>

***

## How augmentation works

`knitkit types sync` generates a file that augments `@knitkit/runtime`'s exported
`RemoteModules` interface. The generated `knitkit-remotes.d.ts` looks like this:

```ts theme={null}
// AUTO-GENERATED by `knitkit types sync`. Do not edit.
import type R0 from "./checkout/CartWidget";
import type R1 from "./checkout/CheckoutButton";
import type R2 from "./profile/NavMenu";

declare module "@knitkit/runtime" {
  interface RemoteModules {
    "checkout/CartWidget": R0;
    "checkout/CheckoutButton": R1;
    "profile/NavMenu": R2;
  }
}
export {};
```

The `RemoteModules` interface is the single source of truth for `loadRemote`'s return type.
When your `loadRemote("checkout/CartWidget")` call resolves, TypeScript looks up
`RemoteModules["checkout/CartWidget"]` and uses that as the return type — giving you
auto-complete on props, refactoring support, and compile-time safety on specifier strings.

***

## `knit.host.json` fields

<ParamField path="remotes" type="Array<{ name: string; manifest: string }>" required>
  Each entry names the remote and provides the URL (or local path) to its
  `knit.manifest.json`. The `name` must match what you pass to `registerRemotes`.
</ParamField>

<ParamField path="typesDir" type="string">
  Directory (relative to `knit.host.json`) where declarations are written. Defaults to
  `".knitkit/types"`.
</ParamField>

***

<Tip>
  Add `.knitkit/types` to your `.gitignore` — these files are generated artifacts, not source
  code. In CI, run `knitkit types sync` as a step before `tsc` or your type-checking lint
  step so the augmentation is always current when types are checked.
</Tip>
