---
title: "Nuxt"
description: "@devframes/nuxt splits into @devframes/nuxt/single (author one devframe) and @devframes/nuxt/hub (mount a hub); the bare import throws."
canonical_url: "https://devfra.me/frameworks/nuxt"
---
# Nuxt

> @devframes/nuxt splits into @devframes/nuxt/single (author one devframe) and @devframes/nuxt/hub (mount a hub); the bare import throws.

`@devframes/nuxt` splits into `@devframes/nuxt/single` (author one devframe) and [`@devframes/nuxt/hub`](#mounting-a-hub) (mount a hub); the bare import throws.

The `single` module wires a Nuxt SPA as a devframe's browser side and types `useNuxtApp().$rpc` as `DevframeRpcClient`.

## Install

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  modules: ['@devframes/nuxt/single'],
})
```

## Using `$rpc`

```vue [app.vue]
<script setup>
const { $rpc } = useNuxtApp()
const payload = await $rpc.call('my-tool:get-payload')
</script>
```

Or a composable:

```ts [composables/usePayload.ts]
export function usePayload() {
  const { $rpc } = useNuxtApp()
  return useAsyncData('payload', () => $rpc.call('my-tool:get-payload'))
}
```

## Options

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  modules: ['@devframes/nuxt/single'],
  devframe: {
    baseURL: './', // where the devframe snapshot lives, relative to the page
    skipAppDefaults: false, // opt out of the app.baseURL / vite.base defaults
  },
})
```

- **`baseURL`** resolves against `document.baseURI` at runtime.
- **`skipAppDefaults: true`** ships absolute asset paths.

## Dev-time RPC bridge

Pass a devframe definition:

```ts [nuxt.config.ts]
import myDevframe from './src/my-tool' // defineDevframe(...) export

export default defineNuxtConfig({
  modules: [
    [
      '@devframes/nuxt/single',
      { devframe: myDevframe }
    ]
  ],
})
```

`nuxt dev` now:

- Starts a WebSocket RPC server on a [`get-port-please`](https://github.com/unjs/get-port-please) port (respects `devframe.cli.port` / `portRange` / `random`).
- Registers Vite middleware at `${baseURL}__connection.json`.
- Runs `devframe.setup(ctx, { flags })`.
- Cleans up on Vite restart, `nuxt dev` shutdown, and bundle close.

On by default when `devframe` is set; disable it (browser side only) with `devMiddleware: false`.

### Customizing the bridge

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  modules: [
    [
      '@devframes/nuxt/single',
      {
        devframe: myDevframe,
        devMiddleware: {
          port: 7777,
          host: '0.0.0.0',
          flags: { config: process.env.MY_CONFIG },
        },
      }
    ]
  ],
})
```

- **`port`** pins the bridge port (else `get-port-please` picks one).
- **`host`** defaults to `nuxt.options.devServer.host ?? devframe.cli?.host ?? 'localhost'`.
- **`flags`** → `devframe.setup(ctx, { flags })`.

### Relationship to `createCac`

Production uses `createCac` (or `createBuild`), producing a static `__connection.json` + `__rpc-dump/` snapshot from `clientAssets`:

```
my-tool/
├── bin.mjs               # createCac(myDevframe).parse()
├── src/
│   ├── my-tool.ts        # defineDevframe + setup(ctx) { ctx.rpc.register(...) }
│   └── app/              # Nuxt SPA, uses `@devframes/nuxt`
└── dist/
    ├── cli.mjs           # bundled Node entry
    └── public/           # Nuxt build output, pointed at by clientAssets
```

## How it works

At build time it sets the `app.baseURL` / `vite.base` defaults, merges `{ devframe: { baseURL } }` into `runtimeConfig.public`, and injects a client-only plugin (`helpers/nuxt/runtime/plugin.client`):

```ts
const rpc = await connectDevframe({ baseURL: config.public.devframe.baseURL })
return {
  provide: { rpc }
}
```

At runtime the SPA fetches `./__connection.json` and branches on `backend`: `websocket` in dev, `static` from a `createBuild` snapshot.

## Mounting a hub

`@devframes/nuxt/hub` mounts a whole [hub](https://devfra.me/guide/hub) alongside `nuxt dev`, injecting `@devframes/hub-ui`'s dock. `ui` swaps the default; `ui: false` gives a headless hub via `@devframes/nuxt/hub/client`.

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  modules: [
    [
      '@devframes/nuxt/hub',
      { devframes: [] }
    ]
  ],
})
```

Nuxt DevTools (`@nuxt/devtools`) integrates the same protocol natively; this module recommends it once (silence with `{ quiet: true }`).

## See also

- [Standalone CLI recipe](https://devfra.me/guide/standalone-cli)
- [Client](https://devfra.me/guide/client): `connectDevframe` reference
- [Adapters](https://devfra.me/adapters)


## Sitemap

See the full [sitemap](https://devfra.me/sitemap.md) for all pages.
