Skip to content

Migrating to 0.9

0.9 removes the compatibility shims that were deprecated across the 0.7 series and trims the public API surface of devframe and @devframes/hub down to what integrations actually consume. Each change has a drop-in replacement, so migrating is a matter of updating import paths and a handful of call sites. This page covers the changes between 0.8.x and 0.9.

Overview

Every entry below has a drop-in replacement. At a glance:

devframe

Removed / movedReplacement
devframe/adapters/cli (createCli, CreateCliOptions, CliHandle)devframe/adapters/cac (createCac, …)
devframe/recipes/open-helpersdevframe/recipes/common-rpc-functions
dump re-exports on the devframe/rpc barreldevframe/rpc/dump
defineDevframe on devframe/typesdefineDevframe on devframe
devframe/utils/promise, devframe/utils/scopePromise.withResolvers() / inline the check
host implementations + low-level factories on devframe/nodeslimmed to createHostContext / createStorage
cross-package internals on devframe/nodedevframe/internal (unstable)
startHttpAndWscreateDevServer / devframe/initiate

@devframes/hub

Removed / movedReplacement
json-render shims (defineJsonRenderSpec, ctx.createJsonRenderer, …)@devframes/json-render
mountDevframectx.install
DEFAULT_CATEGORIES_ORDER re-exports@devframes/hub/constants

devframe/adapters/cli is removed

The CLI adapter was renamed to cac in 0.7. The devframe/adapters/cli entry - createCli, CreateCliOptions, and CliHandle - is now gone. Import from devframe/adapters/cac instead:

0.8.x0.9
import { createCli } from 'devframe/adapters/cli'import { createCac } from 'devframe/adapters/cac'
CreateCliOptionsCreateCacOptions
CliHandleCacHandle
ts
// 0.8.x
import { createCli } from 'devframe/adapters/cli'

await createCli(devframe).parse()
ts
// 0.9
import { createCac } from 'devframe/adapters/cac'

await createCac(devframe).parse()

The typed-flag helpers defineCliFlags and parseCliFlags live on devframe/adapters/cac too. See CLI (cac) for the full adapter reference.

devframe/recipes/open-helpers is removed

The recipe was renamed to common-rpc-functions in 0.7.16. Import commonRpcFunctions from devframe/recipes/common-rpc-functions:

ts
// 0.8.x
import { openHelpers } from 'devframe/recipes/open-helpers'
ts
// 0.9
import { commonRpcFunctions } from 'devframe/recipes/common-rpc-functions'

The openInEditor and openInFinder members are unchanged. See Common RPC functions for the full reference.

RPC dump re-exports move to devframe/rpc/dump

The static-dump helpers and types are served from the dedicated devframe/rpc/dump entry; the aliases that re-exported them from the top-level devframe/rpc barrel are removed. Import them from devframe/rpc/dump:

ts
// 0.8.x
import { createClientFromDump, dumpFunctions } from 'devframe/rpc'

// 0.9
import { createClientFromDump, dumpFunctions } from 'devframe/rpc/dump'

This applies to every dump export - collectStaticRpcDump, createClientFromDump, dumpFunctions, getDefinitionsWithDumps, reviveDumpError, serializeDumpError, and the StaticRpcDump* types.

@devframes/hub json-render shims are removed

json-render moved out of the hub into the opt-in @devframes/json-render integration in 0.7. The hub-local compatibility shims are now removed: the defineJsonRenderSpec helper, the ctx.createJsonRenderer factory, the DevframeViewJsonRender dock type, and the JsonRenderSpec / JsonRenderElement / JsonRenderer types.

0.8.x (@devframes/hub)0.9 (@devframes/json-render)
defineJsonRenderSpec(spec)Pass the spec directly to createJsonRenderView(ctx, { id, spec })
ctx.createJsonRenderer(spec)createJsonRenderView(ctx, { id, spec }) (from @devframes/json-render/node)
JsonRenderSpecDevframeJsonRenderSpec
JsonRenderElementelement shape of DevframeJsonRenderSpec
JsonRendererJsonRenderView
DevframeViewJsonRenderDevframeJsonRenderDockEntry (from @devframes/json-render/hub)
ts
// 0.8.x
import { defineJsonRenderSpec } from '@devframes/hub'

const spec = defineJsonRenderSpec({ root: 'panel', elements: { /* ... */ } })
const renderer = ctx.createJsonRenderer(spec)
ts
// 0.9
import { createJsonRenderView } from '@devframes/json-render/node'

const view = createJsonRenderView(ctx, {
  id: 'panel',
  spec: { root: 'panel', elements: { /* ... */ } },
})

createJsonRenderView returns a view carrying a serializable ref (a shared-state key or an inline spec). Project it onto a hub dock with toJsonRenderDockEntry from @devframes/json-render/hub, which contributes the 'json-render' dock type to the hub's open dock union. A dock entry now carries that serializable view ref rather than a live renderer handle - a client reads entry.view.stateKey (or entry.view.spec) to render it.

See JSON-Render for the full integration reference.

defineDevframe moves to the package root

defineDevframe - the primary authoring helper - now lives on the devframe entry point alongside defineRpcFunction. devframe/types is now strictly type-only. Import both values and types from devframe:

0.8.x0.9
import { defineDevframe } from 'devframe/types'import { defineDevframe } from 'devframe'
import type { DevframeNodeContext } from 'devframe/types'import type { DevframeNodeContext } from 'devframe'
ts
import type { DevframeNodeContext } from 'devframe'
// 0.9
import { defineDevframe, defineRpcFunction } from 'devframe'

devframe/types still resolves as the type-only subpath - useful for declare module 'devframe/types' augmentations - but devframe is the canonical import for both values and types.

devframe/utils/{promise,scope} are removed

Two utility subpaths with no integration consumers are removed:

RemovedReplacement
import { promiseWithResolver } from 'devframe/utils/promise'Promise.withResolvers() (native)
import { isQualifiedName, qualifyName } from 'devframe/utils/scope'Inline the check (name.includes(':'))

The other devframe/utils/* helpers - colors, open, launch-editor, hash, nanoid, crypto-token, structured-clone, events, shared-state, streaming-channel, when, simple-schema, serve-static, agent-tool-name - are unchanged.

devframe/node is slimmed to the context surface

devframe/node keeps just the context-building API - createHostContext (+ CreateHostContextOptions), createStorage (+ CreateStorageOptions), and the RpcFunctionsHost type. Serve a devframe through the adapters (createDevServer, createBuild, createCac) or devframe/initiate; build a context to embed one with createHostContext.

The internal host implementations and low-level factories are no longer exported at all:

Removed from devframe/nodeNotes
DevframeDiagnosticsHost, DevframeServicesHostImpl, DevframeViewHost (classes)Internal host implementations. The same-named types remain on devframe/types.
createRpcSharedStateServerHost, createRpcStreamingServerHostWired internally by createContextRpcServer.
createScopedNodeContext, createNodeSettingsInternal to context assembly.
toDialableHost, formatHostForUrl, isObjectInternal helpers (isObject is removed entirely - inline typeof x === 'object' && x !== null).

Cross-package internals move to devframe/internal

The low-level primitives shared between devframe and its first-party integrations (@devframes/hub, the inspect plugin, @vitejs/devtools, custom hosts) now live at the new devframe/internal entry point, which is explicitly unstable (it can change in any minor release). They were previously on devframe/node:

MovedFromTo
createH3DevframeHost (+ CreateH3DevframeHostOptions)devframe/nodedevframe/internal
StartedServer (the createDevServer return handle)devframe/nodedevframe/internal
DevframeAgentHost (class)devframe/nodedevframe/internal
coerceAgentPositionalArgs (+ AgentArgsFallback)devframe/nodedevframe/internal
registerDevframeInstance / listLiveDevframeInstances (+ DevframeInstanceRecord, DevframeInstanceRegistration)devframe/nodedevframe/internal
normalizeHttpServerUrldevframe/nodedevframe/internal

A host that stands up its own server composes from devframe/internal - createH3DevframeHost for the node DevframeHost, plus createContextRpcServer and a transport from devframe/rpc/transports/* to bind the RPC socket - alongside devframe/node's createHostContext and devframe/node/hub-internals. A custom host advertises itself with registerDevframeInstance, and a devtool enumerates running instances with listLiveDevframeInstances. Application code should prefer the adapters and devframe/initiate.

startHttpAndWs is removed

The low-level "listen on a port + attach the WS transport" primitive is gone. createDevServer, initDevframe, and initHub own that binding internally now, resolving the transport from their own server / ws options - so the common paths never touch it. StartHttpAndWsOptions is removed with it; StartedServer stays (it is still createDevServer's return handle, re-exported from devframe/internal).

0.8.x0.9
startHttpAndWs({ context, port, ... }) for a standalone toolcreateDevServer(def, { port, ... })
startHttpAndWs(...) inside a framework hostinitDevframe(def, { base, ... }) / initHub({ base, ... })

A host that genuinely binds its own transport - a bare RPC socket, or a server it wires itself - composes the two primitives the adapters use underneath: createContextRpcServer (devframe/internal) for the session/auth wiring, and a transport from devframe/rpc/transports/*.

ts
// 0.9 - bind the RPC socket onto a server you own
import { createServer } from 'node:http'
import { createContextRpcServer } from 'devframe/internal'
import { attachWsRpcTransport } from 'devframe/rpc/transports/ws-server'

const httpServer = createServer()
const { rpcGroup, onConnected, onDisconnected } = createContextRpcServer({ context, auth: false })
attachWsRpcTransport(rpcGroup, { server: httpServer, onConnected, onDisconnected })
httpServer.listen(port)

@devframes/hub's mountDevframe is removed - use ctx.install

The free mountDevframe(ctx, def, options) function is replaced by an install method on the hub context. MountDevframeOptions is renamed InstallDevframeOptions. initHub's declarative devframes list runs the same install path under the hood, so most hosts never call it directly.

0.8.x0.9
import { mountDevframe } from '@devframes/hub/node'removed - call ctx.install
await mountDevframe(ctx, def, opts)await ctx.install(def, opts)
MountDevframeOptionsInstallDevframeOptions (from @devframes/hub/node)
ts
// 0.8.x
import { createHubContext, mountDevframe } from '@devframes/hub/node'

const ctx = await createHubContext({ host, cwd, mode: 'dev' })
await mountDevframe(ctx, myDevframe)
ts
// 0.9
import { createHubContext } from '@devframes/hub/node'

const ctx = await createHubContext({ host, cwd, mode: 'dev' })
await ctx.install(myDevframe)

@devframes/hub category order lives only on /constants

DEFAULT_CATEGORIES_ORDER is now exported only from @devframes/hub/constants (its documented single source of truth). The redundant re-exports from @devframes/hub, @devframes/hub/node, and @devframes/hub/client are removed:

ts
// 0.9
import { DEFAULT_CATEGORIES_ORDER } from '@devframes/hub/constants'

Released under the MIT License.