DevTools
Instrumentation and React hooks for debugging and monitoring local AI applications.
DevTools
Instrumentation and React hooks for inspecting model cache, vector database stats, inference queue metrics, pipeline execution traces, and live event streams in LocalMode applications.
Overview
@localmode/devtools provides headless instrumentation (enableDevTools()) plus React hooks (@localmode/devtools/react) that give you full visibility into your local AI application at runtime — all without any telemetry or data leaving your device. The hooks are the primary integration path: subscribe to any slice of the observability bridge and render it in your own UI, with your own styling.
See it in action
DevTools instrumentation is enabled across the LocalMode blocks gallery — open any block and use the DevTools drawer to inspect live model, VectorDB, and queue state.
What you can observe
- Models — Cached models, load times, status
- VectorDB — Collections, document counts, search stats
- Queue — Live inference queue: pending, active, completed, latency
- Pipeline — Step execution traces with timings
- Events — Live event stream with filtering
- Device — WebGPU, WASM, Chrome AI, WebNN capabilities
- Storage — Storage quota usage
Installation
pnpm add -D @localmode/devtoolsQuick Start
Enable instrumentation once, then subscribe to any data domain with a hook:
import { enableDevTools } from '@localmode/devtools';
import { useDevToolsQueueStats, useDevToolsEvents } from '@localmode/devtools/react';
if (process.env.NODE_ENV === 'development') {
enableDevTools();
}
function Observability() {
const queues = useDevToolsQueueStats();
const events = useDevToolsEvents({ types: ['vectordb'], limit: 50 });
return (
<div>
{Object.entries(queues).map(([name, stats]) => (
<p key={name}>{name}: {stats.pending} pending, {stats.active} active</p>
))}
{events.map((e) => (
<p key={e.id}>{e.type}</p>
))}
</div>
);
}If you only want instrumentation without any UI, calling enableDevTools() alone is enough — data is written to the bridge and you can inspect window.__LOCALMODE_DEVTOOLS__ directly.
React Hooks
@localmode/devtools/react exports nine hooks — one per bridge data domain — all built on useSyncExternalStore with version-keyed immutable snapshots:
| Hook | Returns |
|---|---|
useDevToolsBridge | The raw bridge object (window.__LOCALMODE_DEVTOOLS__), or null when absent |
useDevToolsStatus | { available, enabled } — bridge availability and instrumentation state |
useDevToolsQueueStats | Live stats per registered inference queue (Record<string, QueueStats>) |
useDevToolsEvents | Recent bridge events, filterable by types with a limit |
useDevToolsModelCache | Per-model load info (Record<string, ModelCacheInfo>) |
useDevToolsPipelineRuns | Pipeline step execution traces (Record<string, PipelineSnapshot>) |
useDevToolsVectorDBs | Per-collection VectorDB operation stats (Record<string, VectorDBSnapshot>) |
useDevToolsStorage | Storage quota snapshot, or null before the first sample |
useDevToolsCapabilities | Device capabilities snapshot, or null before detection |
Guarantees shared by all hooks:
- Subscribe on mount, fully unsubscribe on unmount — no leaks
- SSR-safe — no
windowaccess during server render; inert values on the server - Inert when devtools is absent — referentially stable fallback values; no errors in production builds
- Late-enable attachment — a hook mounted before
enableDevTools()attaches once the bridge appears, no remount needed - Immutable snapshots — slice hooks return fresh copies per notification; they never alias the bridge's mutable objects
Prebuilt UI: the ui/devtools family + drawer
Prefer copy-owned components to hand-rolling panels? The ui/devtools
family ships four theme-aware,
zero-dependency primitives (inference-queue-monitor, event-log-viewer,
pipeline-run-inspector, model-cache-table) that render these hooks'
output, and npx shadcn add @localmode/ui/blocks/devtools-drawer installs a
composed six-tab observability drawer (Queue / Events / Pipeline / Models /
Device / VectorDB — off by default, zero-overhead when closed). These are the
successor UI to the removed widget (see below).
How It Works
enableDevTools() subscribes to existing observability hooks in @localmode/core:
globalEventBusfor VectorDB and embedding eventsqueue.on('stats')for inference queue metricsonProgresscallbacks for pipeline step tracesgetStorageQuota()for storage usagedetectCapabilities()for device features
Data is written to window.__LOCALMODE_DEVTOOLS__. The React hooks read this bridge directly via subscribe() for instant, non-polling updates. Zero core changes needed — DevTools is a pure read-only visualization layer.
DevToolsWidget (removed in v3.0.0)
Removed in v3.0.0
The prebuilt DevToolsWidget overlay and its @localmode/devtools/widget
subpath were removed in v3.0.0. Its replacements are the React
hooks above (build your own panel with your own styling), the
copy-owned ui/devtools family
primitives (inference-queue-monitor, event-log-viewer,
pipeline-run-inspector, model-cache-table), and the composed six-tab
ui/blocks/devtools-drawer (npx shadcn add @localmode/ui/blocks/devtools-drawer).
The data layer — enableDevTools(), the window.__LOCALMODE_DEVTOOLS__
bridge, and every collector — is unchanged; only the widget UI was removed.
See Data Domains for the six domains the bridge
collects — each maps 1:1 to a /react hook, a ui/devtools primitive, and a
tab of the drawer.
Requirements
@localmode/core^1.0.0 (peer dependency)react>=18.0.0 (peer dependency, only for the/reacthooks)
Composed Block
| Block | Description | Links |
|---|---|---|
| DevTools Drawer | Six-tab global observability drawer composing the @localmode/devtools bridge and hooks across the /blocks gallery | Live · Install: npx shadcn add @localmode/ui/blocks/devtools-drawer |