universa-kit
v0.1.2
Published
Universal bridge for in-browser development tools with cross-framework adapters, same-origin APIs, and runtime control.
Maintainers
Readme

UniversaKit
UniversaKit is a framework-agnostic bridge for local developer tools. It mounts a same-origin control plane (/__universa/*) on your app's dev server so browser overlays, CLIs, and helper scripts can all use one protocol for:
- bridge health/state
- runtime start/restart/stop
- websocket events
- proxying tool APIs through the host origin
Table of Contents
- Who is this for?
- Installation
- Problem this solves
- What it provides
- Use cases
- Quick start (Vite)
- Core concepts
- Integration surfaces
- Public API reference
- Configuration
- Protocol summary
- Usage examples
- Architecture overview
- Design caveats
- Compatibility
- Additional docs
Who is this for?
Use UniversaKit directly if you are building a developer tool package (overlay/sidebar/panel/CLI companion) that should work across frameworks.
If you are an end user of a tool that already ships UniversaKit integration, use that tool's setup docs instead.
Installation
npm i universa-kitpnpm add universa-kityarn add universa-kitbun add universa-kitProblem this solves
Framework dev servers expose different middleware/plugin APIs, so local tooling integrations are often framework-specific. UniversaKit standardizes this with one same-origin bridge contract mounted onto the host dev server.
What it provides
- same-origin bridge endpoints under
/__universa/* - runtime lifecycle control (
start/restartrequirecommand;stopis idempotent) - runtime status and capability reporting for UIs/automation
- websocket event stream with protocol versioning
/api/*passthrough proxy from host origin to runtime origin- framework/server/build-tool adapter surfaces plus a preset API for tool packages
Non-goals:
- no first-party UI or hosted service
- no requirement that end users import UniversaKit directly when a tool already wraps it
Use cases
- devtool overlays/sidebars/panels that should run across frameworks
- local CLIs/scripts that need runtime status and control via the same bridge
- internal developer platforms that expose same-origin local control APIs
Quick start (Vite)
// vite.config.ts
import { createUniversaVitePlugin } from "universa-kit/vite";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [
createUniversaVitePlugin({
command: "node",
args: ["./scripts/dev-runtime.js"],
}),
],
});Core concepts
- Bridge path prefix: defaults to
/__universa. - Runtime helper: optional process manager for your tool runtime command.
- Protocol version: current bridge protocol is
1. - Preset API: recommended integration API for tool authors so users configure one entry point (
mytool().vite(),mytool().next(...), etc.).
Integration surfaces
| Host setup | Import path |
| ------------------------------------------------------------------------------------------ | -------------------------- |
| Vite-based dev servers (React, Vue, Solid, SvelteKit, Remix, TanStack Start, Vinext, etc.) | universa-kit/vite |
| Next.js | universa-kit/next |
| Nuxt | universa-kit/nuxt |
| Astro | universa-kit/astro |
| Angular CLI proxy flow | universa-kit/angular/cli |
| Bun.serve | universa-kit/bun |
| Node middleware + HTTP server | universa-kit/node |
| Fastify | universa-kit/fastify |
| Hono on Node server | universa-kit/hono |
| webpack-dev-server | universa-kit/webpack |
| Rsbuild dev server | universa-kit/rsbuild |
| Rspack dev server | universa-kit/rspack |
Public API reference
Primary exports
| API | Import |
| ----------------------------------------- | ----------------------------- |
| createUniversaPreset | universa-kit/preset |
| createUniversaClient | universa-kit/client |
| createClientRuntimeContext | universa-kit/client-runtime |
| startStandaloneUniversaBridgeServer | universa-kit |
| createUniversaBridge / UniversaBridge | universa-kit |
Adapter naming conventions
createUniversa*: build a plugin/module/integration instance.withUniversa*: wrap and return config.attachUniversaTo*: attach to an existing server.startUniversa*: start helper/standalone utilities.
For expanded API coverage (including lifecycle helpers, runtime-context utilities, and adapter-specific helper exports), see INTEGRATION_GUIDE.md.
Configuration
Most adapter APIs accept shared bridge/runtime options.
| Option | Type | Default | Notes |
| -------------------------- | ------------------------------------- | ------------------------- | ----------------------------------------------------------------- |
| bridgePathPrefix | string | "/__universa" | Normalized to stay rooted under /__universa. |
| autoStart | boolean | true | Auto-start runtime on state/proxy/events paths. |
| command | string | none | Required for managed runtime start/restart. |
| args | string[] | [] | Runtime command args. |
| cwd | string | process.cwd() | Runtime working directory. |
| env | Record<string, string \| undefined> | none | Extra runtime environment variables. |
| host | string | "127.0.0.1" | Runtime host binding. |
| healthPath | string | "/api/version" | Runtime health probe endpoint. |
| startTimeoutMs | number | 15000 | Runtime startup timeout. |
| runtimePortEnvVar | string | "UNIVERSA_RUNTIME_PORT" | Env var populated with selected runtime port. |
| fallbackCommand | string | "universa dev" | Returned in some runtime-control error payloads. |
| eventHeartbeatIntervalMs | number | 30000 | WS heartbeat for stale client cleanup. |
| proxyRuntimeWebSocket | boolean | true | Enables runtime websocket proxying through bridge events socket. |
| instance | { id: string; label?: string } | none | Optional instance metadata in bridge state/health. |
| clientModule | string | none | Dev-only side-effect module injection (typically set by presets). |
Preset-specific options (createUniversaPreset)
identity(required):{ packageName: string; variant?: string }client.module: module specifier to inject in developmentclient.enabled: enable/disable client module injectionclient.autoMount: default auto-mount hintcomposition:"registry" | "local"instanceId: stable suffix for multiple preset instancesunsafeOverrides: advanced adapter identity overrides
Protocol summary
With prefix /__universa (or /__universa/<namespaceId> for presets):
GET /healthGET /stateGET /runtime/statusPOST /runtime/startPOST /runtime/restartPOST /runtime/stopWS /eventsANY /api/*proxied to runtime/api/*
Behavior highlights:
- Route matching is query-safe.
GET /statemay auto-start runtime whenautoStartis enabled.POST /runtime/stopis idempotent and disables auto-start until start/restart.- Bridge-generated errors use
{ success: false, message, error }envelope. - Proxied
/api/*responses pass through status/headers/body (including non-2xx).
For normative protocol details, see PROTOCOL.md.
For adapter-specific snippets (Next keying, Bun/Node/Fastify/Hono servers, webpack/Rsbuild/Rspack, Astro/Nuxt, Angular CLI, and standalone bridge usage), see INTEGRATION_GUIDE.md.
Usage examples
Preset export for your tool package
import { createUniversaPreset } from "universa-kit/preset";
export function myTool() {
return createUniversaPreset({
identity: { packageName: "mytool" },
command: "mytool",
args: ["dev"],
fallbackCommand: "mytool dev",
client: {
module: "mytool/overlay",
autoMount: true,
},
});
}Next.js
// next.config.ts
import { myTool } from "mytool";
export default myTool().next({ reactStrictMode: true });Vite (including Vinext)
// vite.config.ts
import { myTool } from "mytool";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [myTool().vite()],
});Client SDK
import { createUniversaClient } from "universa-kit/client";
const client = createUniversaClient({ namespaceId: "mytool" });
const state = await client.getState();
const unsubscribe = client.subscribeEvents((event) => {
console.log(event.type, event.eventId);
});
unsubscribe();Architecture overview
High-level internals:
src/bridge/*: HTTP/WS routing, runtime control routes, proxying, event fanout.src/runtime/runtime-helper.ts: command lifecycle and health probing.src/adapters/*: framework/server/build-tool integration points.src/client/*: typed browser/Node client helpers.src/preset.ts+src/preset-registry.ts: preset composition and registry behavior.
For implementation details, see ARCHITECTURE.md.
Design caveats
- UniversaKit does not ship a first-party UI.
- Runtime start/restart are unavailable when
commandis not configured. bridgePathPrefixis normalized under/__universa.- Package is ESM-only (
"type": "module").
Compatibility
- Runtime targets: Node.js and Bun.
- Package format: ESM-only (
"type": "module").
Additional docs
INTEGRATION_GUIDE.md: end-to-end guide for tool authors, adapter cookbook, and expanded API coverage.PROTOCOL.md: normative bridge contract.ARCHITECTURE.md: internal architecture.EXAMPLES.md: workspace example setup and verification.
Docs checks:
bun run docs:lint
bun run docs:check