A framework-neutral foundation for devtools. One definition becomes a Web Standard handler you can mount into any host framework, ship as a CLI or static report, and expose to coding agents.
import { defineDevframe } from 'devframe'
import { initDevframe } from 'devframe/initiate'
const myDevframe = defineDevframe({
id: 'my-tool',
name: 'My Tool',
rpc: [getModules],
view: { type: 'spa', distDir: './dist/client' },
})
// one Request → Response handler, any host framework
const { handler } = initDevframe(myDevframe, {
base: '/__my-tool/',
})// Foundation //
One definition, every entry point
defineDevframe() describes a tool once. initDevframe() turns it into a Web Standard Request → Response handler, and adapters reshape that same definition into whatever your package ships.
One Standard Handler
Mount the same handler into Hono, Nitro, Next.js, SvelteKit, Vite, Rsbuild, Deno, or Bun.
Adapters as Conveniences
The same definition also becomes a standalone CLI, a dev server, a static report, an MCP server, or a Vite DevTools dock.
Type-safe RPC & Shared State
Bidirectional calls built on birpc, validated against any Standard Schema validator, plus observable patch-synced state that survives reconnects.
Visual and Agentic
Expose the same internal state to a web UI and to coding agents over MCP: one source of truth, two interfaces.
// Portability //
The same handler, mounted natively
A devframe's boundary is simply the Web Standard Request and Response. Any framework that speaks that (or connect-style middleware) mounts the same tool and inherits the whole ecosystem. Only the host-framework-facing glue changes. See all adapters.
// Adapters //
Package it the way your tool ships
The handler is the smallest common denominator. Higher-level adapters package that same definition into familiar forms; pick the entry points your package needs. Browse the adapters.
// Interfaces //
One capability, two interfaces
RPC functions stay private by default and opt into agent exposure explicitly. The MCP adapter translates those functions, resources, and selected shared state into an agent-consumable interface: the presentation changes, the source of truth stays the same.
// Hub //
From one devframe to a devtools hub
When several devtools run at once, discovery becomes the problem. @devframes/hub is a headless composition layer: many devframes register docks, commands, terminals, and shared state, and appear through one consistent entry. Learn about the hub.
Ship your devtool everywhere
Start from one DevframeDefinition and pick the entry points your package ships: hosted, standalone, embedded, or agentic.