# Unplugin

Source: https://permdock.com/docs/cli/unplugin

createPermDockUnplugin runs permdock collect in Vite, Rollup, webpack, Rspack and esbuild so Nuxt, Astro, React Router, TanStack Start and Effect apps stay catalog-fresh without a per-vendor package.

`createPermDockUnplugin` is exported from `permdock/unplugin`. It is the same collect-only hook as [`createPermDockPlugin`](/docs/cli/next-plugin), built with [unplugin](https://unplugin.unjs.io) so one implementation covers Vite, Rollup, webpack, Rspack and esbuild. It never aliases modules, never creates a `PermDock`, and never belongs on a request path. `unplugin` is an optional peer of `permdock`: add it with `pnpm add -D unplugin` (importing `permdock/unplugin` without it throws that install line).

There is no `permdock/nuxt`, `permdock/astro`, `permdock/react-router`, `permdock/tanstack-start` or `permdock/effect`. Runtime wiring uses the UI and HTTP adapters; this hook only keeps the catalog honest.

## Usage [#usage]

```ts
import { createPermDockUnplugin } from "permdock/unplugin";

export default {
  plugins: [
    createPermDockUnplugin.vite({
      collect: { srcPath: ["./src", "../ui/src"] },
    }),
  ],
};
```

Adapters on the factory: `createPermDockUnplugin.vite()`, `.rollup()`, `.webpack()`, `.rspack()`, `.esbuild()`. Options match the Next plugin (`collect.srcPath`, `collect.out`, `collect.barrel`, `onDrift`). `buildStart` writes the catalog by default; `check: true` makes it compare instead, and a stale catalog fails the build unless `onDrift: 'warn'`. `watchChange` re-runs collect for every changed file except the catalog and barrel it wrote, debounced and one run at a time, and logs failures without stopping the dev server. `permdock.config.ts` is read when options are omitted.

## Recipes [#recipes]

### TanStack Start [#tanstack-start]

Vite plugin. UI is `permdock/react`. Server functions use `permdock/server` or `permdock/node`. Load the snapshot in a server function or loader and pass it to `PermDockProvider` ([UI](/docs/concepts/ui)).

```ts
// vite.config.ts
import { defineConfig } from "vite";
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
import { createPermDockUnplugin } from "permdock/unplugin";

export default defineConfig({
  plugins: [createPermDockUnplugin.vite(), tanstackStart()],
});
```

### React Router 7 [#react-router-7]

Vite plugin. Same runtime as TanStack Start: `permdock/react` plus a Fetch or Node factory. Snapshot in the route `loader`.

```ts
// vite.config.ts
import { reactRouter } from "@react-router/dev/vite";
import { createPermDockUnplugin } from "permdock/unplugin";
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [createPermDockUnplugin.vite(), reactRouter()],
});
```

### Nuxt [#nuxt]

Vite plugin under `vite.plugins`. Client UI is `permdock/vue`. A server route (Nitro) builds the snapshot with `permdock/server`. Do not put the policy in a Nuxt plugin that ships to the browser.

```ts
// nuxt.config.ts
import { createPermDockUnplugin } from "permdock/unplugin";

export default defineNuxtConfig({
  vite: {
    plugins: [createPermDockUnplugin.vite()],
  },
});
```

### Astro [#astro]

Vite plugin on `astro.config`. Islands use `permdock/react`, `permdock/vue` or `permdock/svelte`. Endpoints use `permdock/server`.

```ts
// astro.config.ts
import { defineConfig } from "astro/config";
import { createPermDockUnplugin } from "permdock/unplugin";

export default defineConfig({
  vite: {
    plugins: [createPermDockUnplugin.vite()],
  },
});
```

### Effect [#effect]

Effect is not a bundler. Three existing paths cover it:

1. **Schema.** Effect Schema 3.13+ via its Standard Schema adapter is a resource schema, same as Zod ([Standard Schema](/docs/standards/standard-schema)). Boundary validation stays synchronous.
2. **HttpApi.** Effect HttpApi has no per-route PermDock hook. Emit OpenAPI, then `permdock openapi emit --format overlay` and apply it ([OpenAPI](/docs/adapters/openapi)).
3. **Collect.** When the app is built with Vite (or webpack / esbuild), add `createPermDockUnplugin` as above. Runtime guards stay `permdock/server` or the HTTP adapter that matches the listener.

## What it does not do [#what-it-does-not-do]

* It does not export `getPermDock`, `usePermission` or `Protected`.
* It does not install a Nuxt module, an Astro integration, or a TanStack / React Router middleware.
* It does not run `usage`, `doctor`, `openapi` or `arazzo check`.
* It does not evaluate a subject.

## Related [#related]

* [Next.js plugin](/docs/cli/next-plugin)
* [collect](/docs/cli/collect)
* [Vue](/docs/adapters/vue), [React](/docs/adapters/react), [server kernel](/docs/adapters/server-kernel)
