Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

**`devframe`** is the framework-neutral container for one devtool integration, portable across hub UI providers. Build a single tool (its RPC, its SPA, its diagnostics, its CLI/build/embedded outputs) without caring how it'll be displayed. A devframe runs standalone (CLI, static deploy, embedded SPA) just as well as it mounts inside a hub.

**`@devframes/hub`** is the framework-neutral hub layer that sits on top of devframe and provides the multi-devframe orchestration (docks, terminals, messages, commands). It does not ship UI - hub UI providers (e.g. `@vitejs/devtools-kit`) provide their own UI on top of the hub's RPC + shared-state protocol. It does ship a **headless client runtime** (`createDevframeClientRuntime()` from `@devframes/hub/client`): booted in the host page, it assembles the shared `DevframeClientContext` (panel, docks, commands, when) and imports each dock entry's client script (`action` / `custom-render` / iframe `clientScript`) into that page - how a built-in devframe like the a11y inspector runs its page script inside the user app's page. See `examples/hub-vite/` for a working ~120-line Vite host demonstrating the protocol end to end.
**`@devframes/hub`** is the framework-neutral hub layer that sits on top of devframe and provides the multi-devframe orchestration (docks, terminals, messages, commands). It does not ship UI - hub UI providers (e.g. `@vitejs/devtools-kit`) provide their own UI on top of the hub's RPC + shared-state protocol. It does ship a **headless client runtime** (`createDevframeClientRuntime()` from `@devframes/hub/client`): booted in the host page, it assembles the shared `DevframeClientContext` (panel, docks, commands, when) and imports each dock entry's client script (`action` / `custom-render` / iframe `clientScript`) into that page - how a built-in devframe like the a11y inspector runs its page script inside the user app's page. See `examples/custom-hub-vite/` for a working ~120-line Vite host demonstrating the protocol end to end.

## Terminology

Expand Down Expand Up @@ -73,7 +73,7 @@ The framework kits - `@devframes/vite`, `@devframes/nuxt`, `@devframes/next` - e
- **`.../hub`** - **mount a whole `@devframes/hub` (many devframes) inside that tool** (the "I'm standing up devtools" scope). Wraps `initHub`, defaults the UI slot to `@devframes/hub-ui`'s `createUi()` (overridable via `ui`, or `ui: false` for headless), and ships a browser client helper at `.../hub/client` (a thin, lifecycle-managing wrapper over `@devframes/hub/client`'s `createDevframeClientRuntime`). `@devframes/hub` and `@devframes/hub-ui` are **optional peers** of these packages; `hub-ui` is loaded lazily (a bundler-ignored dynamic `import()` in the Next hub) so it stays optional and its `import.meta.url` asset lookups resolve at request time.
- **The bare root (`.`) throws** a helpful error pointing at the two subpaths - never put real code on it.
- **Vite and Nuxt already have native hub UI providers** (`@vitejs/devtools-kit`, `@nuxt/devtools`), so `@devframes/vite/hub` and `@devframes/nuxt/hub` still work but emit a one-time `console.warn` recommending those (silence with `{ quiet: true }`). `@devframes/next/hub` has no native counterpart, so it warns nothing.
- The **full hub examples** (`examples/hub-vite`, `examples/hub-next`) consume `.../hub` on the node side but keep hand-rolling their own hub UI provider against `@devframes/hub/client` with `ui: false` - that hand-rolled hub UI provider is the whole point of those reference hosts. The **minimal** ones (`examples/hub-*-minimal`) consume `.../hub` with the default `@devframes/hub-ui` and inject its `embedded.js`, needing no browser-side code.
- The **full hub examples** (`examples/custom-hub-vite`, `examples/custom-hub-next`) consume `.../hub` on the node side but keep hand-rolling their own hub UI provider against `@devframes/hub/client` with `ui: false` - that hand-rolled hub UI provider is the whole point of those reference hosts. The **minimal** ones (`examples/hub-vite`, `examples/hub-next`, `examples/hub-deno`, `examples/hub-fastify`, `examples/hub-hono`, `examples/hub-nitro`, `examples/hub-rsbuild`, `examples/hub-sveltekit`) consume `.../hub` with the default `@devframes/hub-ui` and inject its `embedded.js`, needing no browser-side code.

### Design system

Expand Down Expand Up @@ -105,7 +105,7 @@ These reinforce devframe's positioning as "the container for one devtool integra

### Hub example parity

`examples/hub-vite/` (Vite plugin + vanilla client) and `examples/hub-next/` (Next.js App Router + React client) are the two reference hosts, and they stay at **feature parity**. They mount the same set of plugins and demo devframes, expose the same dock rail / iframe stage / subsystem drawer, and speak the same hub protocol - the only differences should be the host framework's own plumbing (how static assets are mounted, how the side-car server starts, how the client is rendered).
`examples/custom-hub-vite/` (Vite plugin + vanilla client) and `examples/custom-hub-next/` (Next.js App Router + React client) are the two reference hosts, and they stay at **feature parity**. They mount the same set of plugins and demo devframes, expose the same dock rail / iframe stage / subsystem drawer, and speak the same hub protocol - the only differences should be the host framework's own plumbing (how static assets are mounted, how the side-car server starts, how the client is rendered).

Any change to one lands in the other in the same PR: adding a dock, wiring a new hub subsystem, changing the drawer layout, adopting a new client-runtime API. Their READMEs mirror each other too. If a capability genuinely can't exist on one host, say so explicitly in both READMEs rather than letting the examples silently drift.

Expand Down
6 changes: 3 additions & 3 deletions docs/app/components/global/DevframeEcosystemMap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ const nodes: EcosystemNode[] = [
linksFrom: 'handler',
label: 'Nitro',
icon: 'i-unjs-nitro',
href: 'https://github.com/devframes/devframe/tree/main/examples/hub-nitro-minimal',
href: 'https://github.com/devframes/devframe/tree/main/examples/hub-nitro',
color: 'neutral',
shape: 'pill',
style: 'dashed',
Expand All @@ -198,7 +198,7 @@ const nodes: EcosystemNode[] = [
linksFrom: { source: 'handler', direction: 'vertical' },
label: 'Hono',
icon: 'i-logos-hono',
href: 'https://github.com/devframes/devframe/tree/main/examples/hub-hono-minimal',
href: 'https://github.com/devframes/devframe/tree/main/examples/hub-hono',
color: 'neutral',
shape: 'pill',
style: 'dashed',
Expand All @@ -211,7 +211,7 @@ const nodes: EcosystemNode[] = [
linksFrom: { source: 'handler', dashed: true, direction: 'vertical' },
label: 'Next.js',
icon: 'i-logos-nextjs-icon',
href: 'https://github.com/devframes/devframe/tree/main/examples/hub-next-minimal',
href: 'https://github.com/devframes/devframe/tree/main/examples/hub-next',
color: 'neutral',
shape: 'pill',
style: 'dashed',
Expand Down
6 changes: 3 additions & 3 deletions docs/content/1.guide/16.hub.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ description: '@devframes/hub orchestrates many devtools sharing a UI: a dock reg

![Hub screenshot](/screenshots/hub-1.png)

_Orchestrating multiple devtools (from [A Playground](https://github.com/devframes/devframe/tree/main/examples/hub-vite))_
_Orchestrating multiple devtools (from [A Playground](https://github.com/devframes/devframe/tree/main/examples/custom-hub-vite))_

## What the hub adds

Expand Down Expand Up @@ -248,8 +248,8 @@ The hub ships a headless client runtime, `createDevframeClientRuntime()` (`@devf

Two minimal hubs mount every built-in devframe behind an icon dock, plus a "Tabbed Tool" demonstrating [shared-iframe soft navigation](/guide/client-context#shared-iframe-soft-navigation):

- [`examples/hub-vite/`](https://github.com/devframes/devframe/tree/main/examples/hub-vite): a ~120-line Vite host with a vanilla DOM UI.
- [`examples/hub-next/`](https://github.com/devframes/devframe/tree/main/examples/hub-next): the same, from a Next.js App Router app.
- [`examples/custom-hub-vite/`](https://github.com/devframes/devframe/tree/main/examples/custom-hub-vite): a ~120-line Vite host with a vanilla DOM UI.
- [`examples/custom-hub-next/`](https://github.com/devframes/devframe/tree/main/examples/custom-hub-next): the same, from a Next.js App Router app.

## Diagnostics

Expand Down
2 changes: 1 addition & 1 deletion docs/content/1.guide/17.client-context.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,4 @@ It materializes a [client-only dock](#client-only-docks) per tab (id `<frameId>:

### The hub UI provider's part

A hub UI provider keeps one iframe alive per `frameId` (shown/hidden); on mount, it sets the element on the anchor's `docks.getStateById(anchorId)` state (`domElements.iframe`) and emits `dom:iframe:mounted`. See the "Tabbed Tool" in [`examples/hub-vite`](https://github.com/devframes/devframe/tree/main/examples/hub-vite) / [`hub-next`](https://github.com/devframes/devframe/tree/main/examples/hub-next).
A hub UI provider keeps one iframe alive per `frameId` (shown/hidden); on mount, it sets the element on the anchor's `docks.getStateById(anchorId)` state (`domElements.iframe`) and emits `dom:iframe:mounted`. See the "Tabbed Tool" in [`examples/custom-hub-vite`](https://github.com/devframes/devframe/tree/main/examples/custom-hub-vite) / [`custom-hub-next`](https://github.com/devframes/devframe/tree/main/examples/custom-hub-next).
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description: '@devframes/json-render-ui is the reference frontend, not the proto
---

`@devframes/json-render-ui` is the reference frontend, not the protocol; any
implementation of the renderer contract replaces it. The [Next hub witness](https://github.com/devframes/devframe/tree/main/examples/hub-next) ships a React one at
implementation of the renderer contract replaces it. The [Next hub witness](https://github.com/devframes/devframe/tree/main/examples/custom-hub-next) ships a React one at
`src/client/json-render/`.

## The contract
Expand Down
4 changes: 2 additions & 2 deletions docs/content/1.guide/22.build-your-own-hub-ui.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,6 @@ Renderer modules self-style (sometimes via a shadow root). Keep a live
## Reference points

- `packages/hub-ui`: the full reference hub UI provider (Vue, `@antfu/design`).
- [`examples/hub-vite`](https://github.com/devframes/devframe/tree/main/examples/hub-vite) and
[`examples/hub-next`](https://github.com/devframes/devframe/tree/main/examples/hub-next): hand-rolled
- [`examples/custom-hub-vite`](https://github.com/devframes/devframe/tree/main/examples/custom-hub-vite) and
[`examples/custom-hub-next`](https://github.com/devframes/devframe/tree/main/examples/custom-hub-next): hand-rolled
hub UI providers in vanilla DOM and React.
20 changes: 10 additions & 10 deletions docs/content/1.guide/23.built-with.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,18 @@ pnpm --filter <example-name> dev
| [json-render](https://github.com/devframes/devframe/tree/main/examples/json-render) | Vue | Server-authored view via `@devframes/json-render-ui`; live state + action bridge. |
| [streaming-chat](https://github.com/devframes/devframe/tree/main/examples/streaming-chat) | Preact | Streams tokens; history in shared state. |
| [next-runtime-snapshot](https://github.com/devframes/devframe/tree/main/examples/next-runtime-snapshot) | React (Next.js) | App Router SPA surfacing the Node runtime. |
| [hub-vite](https://github.com/devframes/devframe/tree/main/examples/hub-vite) | Vanilla TS (Vite) | ~120-line Vite host wiring `@devframes/hub`; hand-built hub UI provider. |
| [hub-next](https://github.com/devframes/devframe/tree/main/examples/hub-next) | React (Next.js) | Same protocol, Next.js route. |
| [custom-hub-vite](https://github.com/devframes/devframe/tree/main/examples/custom-hub-vite) | Vanilla TS (Vite) | ~120-line Vite host wiring `@devframes/hub`; hand-built hub UI provider. |
| [custom-hub-next](https://github.com/devframes/devframe/tree/main/examples/custom-hub-next) | React (Next.js) | Same protocol, Next.js route. |

The **minimal** family mounts `initHub({ ui: createUi() })` with `@devframes/hub-ui`:

| Example | Host framework | Shows |
|---------|------|-------|
| [hub-vite-minimal](https://github.com/devframes/devframe/tree/main/examples/hub-vite-minimal) | Vite | Dev middleware. |
| [hub-next-minimal](https://github.com/devframes/devframe/tree/main/examples/hub-next-minimal) | Next.js | App Router route. |
| [hub-nitro-minimal](https://github.com/devframes/devframe/tree/main/examples/hub-nitro-minimal) | Nitro | Catch-all route. |
| [hub-hono-minimal](https://github.com/devframes/devframe/tree/main/examples/hub-hono-minimal) | Hono | Node and Bun. |
| [hub-fastify-minimal](https://github.com/devframes/devframe/tree/main/examples/hub-fastify-minimal) | Fastify | `nodeMiddleware`. |
| [hub-sveltekit-minimal](https://github.com/devframes/devframe/tree/main/examples/hub-sveltekit-minimal) | SvelteKit | Catch-all endpoint. |
| [hub-deno-minimal](https://github.com/devframes/devframe/tree/main/examples/hub-deno-minimal) | Deno | `Deno.serve` + upgrade socket. |
| [hub-rsbuild-minimal](https://github.com/devframes/devframe/tree/main/examples/hub-rsbuild-minimal) | Rsbuild | Dev middleware. |
| [hub-vite](https://github.com/devframes/devframe/tree/main/examples/hub-vite) | Vite | Dev middleware. |
| [hub-next](https://github.com/devframes/devframe/tree/main/examples/hub-next) | Next.js | App Router route. |
| [hub-nitro](https://github.com/devframes/devframe/tree/main/examples/hub-nitro) | Nitro | Catch-all route. |
| [hub-hono](https://github.com/devframes/devframe/tree/main/examples/hub-hono) | Hono | Node and Bun. |
| [hub-fastify](https://github.com/devframes/devframe/tree/main/examples/hub-fastify) | Fastify | `nodeMiddleware`. |
| [hub-sveltekit](https://github.com/devframes/devframe/tree/main/examples/hub-sveltekit) | SvelteKit | Catch-all endpoint. |
| [hub-deno](https://github.com/devframes/devframe/tree/main/examples/hub-deno) | Deno | `Deno.serve` + upgrade socket. |
| [hub-rsbuild](https://github.com/devframes/devframe/tree/main/examples/hub-rsbuild) | Rsbuild | Dev middleware. |
2 changes: 1 addition & 1 deletion docs/content/1.guide/8.json-render.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ view renders full-bleed, multiple get a `title`-labeled switcher.
A custom frontend renders from shared state: connect with `connectDevframe()`,
read the view's state (keyed `devframe:json-render:<scope>:<id>`), subscribe to
`updated` events, and render with your registry; the [Next
hub example](https://github.com/devframes/devframe/tree/main/examples/hub-next) has a React renderer. In a
hub example](https://github.com/devframes/devframe/tree/main/examples/custom-hub-next) has a React renderer. In a
**static** build spec + state are read-only: actions unavailable, local
state and bindings still work.

Expand Down
4 changes: 2 additions & 2 deletions docs/content/3.frameworks/3.next.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export const GET = handler.fetch

## Hosting a hub

[`@devframes/hub`](/guide/hub)'s `initHub` mounts every devframe under `<base><id>/` behind one `handler` (memoize on `globalThis`; see `examples/hub-next`):
[`@devframes/hub`](/guide/hub)'s `initHub` mounts every devframe under `<base><id>/` behind one `handler` (memoize on `globalThis`; see `examples/custom-hub-next`):

```ts [devframe/host.ts]
import { DEVFRAMES_HUB_BASE, initHub } from '@devframes/hub/initiate'
Expand Down Expand Up @@ -133,4 +133,4 @@ No native hub UI provider here, so this scope stays quiet; `createDevframeNextHo

- [Vite](/frameworks/vite)
- [Hub](/guide/hub)
- [hub-next](https://github.com/devframes/devframe/tree/main/examples/hub-next)
- [custom-hub-next](https://github.com/devframes/devframe/tree/main/examples/custom-hub-next)
2 changes: 1 addition & 1 deletion docs/content/6.errors/DF0076.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ hub.attach(myNodeHttpServer) // ✗ throws DF0076 on Bun/Deno

## Fix

On Bun/Deno, serve the advertised `__ws` route from `Bun.serve` / `Deno.serve` and complete the upgrade with `attachBunWsTransport` / `attachDenoWsTransport` (see the `hub-deno-minimal` example), or connect over the SSE endpoint instead; it rides the instance's ordinary HTTP surface and needs no upgrade wiring. A side-car (`ws: { sidecar: true }`) also binds the native WebSocket adapter for you on its own port.
On Bun/Deno, serve the advertised `__ws` route from `Bun.serve` / `Deno.serve` and complete the upgrade with `attachBunWsTransport` / `attachDenoWsTransport` (see the `hub-deno` example), or connect over the SSE endpoint instead; it rides the instance's ordinary HTTP surface and needs no upgrade wiring. A side-car (`ws: { sidecar: true }`) also binds the native WebSocket adapter for you on its own port.

## Source

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ hub.nodeMiddleware

Mounted devframes share one RPC registry, state store, connection, authentication gate, and optional aggregate MCP endpoint. The hub remains headless: [`@devframes/hub-ui`](/guide/hub-initiate#the-ui-slot) provides the reference hub UI provider, while a product can supply another hub UI provider independently of the underlying tools.

Like a single devframe, a hub can mount into almost any host framework through the standard handler. The repository includes working reference projects for [Vite](https://github.com/devframes/devframe/tree/main/examples/hub-vite-minimal), [Next.js](https://github.com/devframes/devframe/tree/main/examples/hub-next-minimal), [Hono](https://github.com/devframes/devframe/tree/main/examples/hub-hono-minimal), [Nitro](https://github.com/devframes/devframe/tree/main/examples/hub-nitro-minimal), and [Rsbuild](https://github.com/devframes/devframe/tree/main/examples/hub-rsbuild-minimal). Each example connects the same handler and UI entry to its host framework's native server API. A complete DevTools host can build its own design system and interaction model on top of the hub's foundation.
Like a single devframe, a hub can mount into almost any host framework through the standard handler. The repository includes working reference projects for [Vite](https://github.com/devframes/devframe/tree/main/examples/hub-vite), [Next.js](https://github.com/devframes/devframe/tree/main/examples/hub-next), [Hono](https://github.com/devframes/devframe/tree/main/examples/hub-hono), [Nitro](https://github.com/devframes/devframe/tree/main/examples/hub-nitro), and [Rsbuild](https://github.com/devframes/devframe/tree/main/examples/hub-rsbuild). Each example connects the same handler and UI entry to its host framework's native server API. A complete DevTools host can build its own design system and interaction model on top of the hub's foundation.

### Vite DevTools

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export interface A11yMessagesPlaygroundOptions {

/**
* A tiny Vite plugin that runs `@devframes/hub` inside the Vite dev server -
* the same shape as `examples/hub-vite`, trimmed to the two plugins this
* the same shape as `examples/custom-hub-vite`, trimmed to the two plugins this
* playground pairs (a11y + messages). One `initHub()` call assembles the whole
* hub: it mounts each devframe as a dock, shares the WebSocket with Vite's own
* server, serves the discovery endpoints, and registers the playground in the
Expand Down
File renamed without changes.
Loading
Loading