Skip to content

Vite

@devframes/vite splits into two scopes: @devframes/vite/dev-spa (this page — dev-serve one devframe's SPA with Vite) and @devframes/vite/hub (mount a whole devframes-hub inside a Vite app). The bare @devframes/vite import throws with a pointer to both.

The dev-spa scope exports two Vite plugins for mounting a single devframe inside an existing Vite dev server — devframeVitePlugin (static mount) and devframeViteBridge (RPC bridge) — plus devframeVite, a convenience wrapper that picks between them. Used by @devframes/nuxt and available for any Vite-based host (Astro, SolidStart, plain Vite apps).

This sits below the vite adapter on the abstraction ladder: the adapter targets the full Vite DevTools dock; these are the lower-level Vite plugins you reach for when you want a devframe to ride along with an existing app's dev server without the DevTools dock.

ts
import { devframeViteBridge, devframeVitePlugin } from '@devframes/vite/dev-spa'
import { defineConfig } from 'vite'
import devframe from './devframe'

export default defineConfig({
  // Statically mounts the built SPA at `/__<id>/` — no RPC server:
  plugins: [devframeVitePlugin(devframe)],
  // Or bridge the RPC/WS backend into this dev server instead — the
  // host app owns the SPA:
  // plugins: [devframeViteBridge(devframe)],
})

devframeVitePlugin — static mount

Mounts def.cli.distDir at options.base (/__<id>/ by default) with SPA fallback. No RPC server is started — useful when you only need the SPA bundle served from a known path.

OptionDefaultDescription
basedef.basePath ?? '/__<id>/'Mount path inside the Vite dev server.

devframeViteBridge — RPC bridge

Skips the static mount — the host app owns the SPA. Devframe spawns a separate RPC + WS server and registers Vite middleware at <base>__connection.json so the host-served SPA can discover the WS endpoint. The side-car listens on its own port unless it can share Vite's own HTTP server, so the descriptor carries that port alongside the /__ws route.

To mount the RPC socket onto the Vite server's own port instead of a side-car — so it shares the origin with the app and rides through a proxy — pass Vite's HTTP server to initDevframe / initHub via the server option. Devframe binds only its own <base>__ws upgrade route and leaves the rest (Vite's HMR socket included) untouched.

OptionDefaultDescription
basedef.basePath ?? '/__<id>/'Mount path inside the Vite dev server.
portshare Vite's HTTP serverPin a side-car port for the RPC socket instead.
hostdef.cli?.host ?? 'localhost'Bind host for a pinned side-car.
flagsForwarded to def.setup(ctx, { flags }).
authgated (interactive OTP)false to opt out for a single-user localhost host, or a DevframeAuthHandler for a custom scheme.
mcpdef.cli?.mcptrue or McpRouteOptions to expose the route-based MCP server at <base>__mcp.

port / host / flags mirror createDevServer's options of the same name.

devframeVite — convenience wrapper

devframeVite(def, { bridge, ...bridgeOptions }) forwards to devframeViteBridge when bridge: true, or devframeVitePlugin otherwise — handy when a single call site needs to switch between the two modes. Reach for the two plugins directly when a devframe needs both mounted at once (e.g. a bridge for RPC alongside a static mount serving its own bundled UI, as the built-in terminals/code-server plugins do).

Mounting a hub

@devframes/vite/hub mounts a whole devframes-hub — many integrations under one namespace, one merged RPC registry — inside a Vite dev server with one viteDevframeHub() plugin. It wraps initHub, shares Vite's HTTP server for the WebSocket, defaults the dock UI to @devframes/hub-ui (injecting its embedded.js bootstrap into the host page), and mounts everything as connect middleware.

ts
import { viteDevframeHub } from '@devframes/vite/hub'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [viteDevframeHub({ devframes: [] })],
})

Pass ui to swap the viewer or ui: false for a headless hub you drive with the client helper at @devframes/vite/hub/client (mountDevframeHubClient()). Vite DevTools (@vitejs/devtools-kit) integrates the same hub protocol natively and is the recommended path for a Vite app, so this plugin prints a one-time recommendation to that effect (silence it with { quiet: true }).

Released under the MIT License.