One Logo Pool Ball
wwwwwwwwwwwwwwwwwww

Dev Tools

One has two development tool surfaces:

Both work in development with no setup. You can add your own panels to the web overlay, and Rozenite plugin packages automatically appear in React Native DevTools.

Opening Dev Tools

For the web overlay, press Alt+Space (Option+Space on Mac) to open the spotlight menu, then select a tool. You can also use keyboard shortcuts to jump directly to a specific panel:

Press Escape to close any panel.

For React Native, press j or dt in the one dev terminal. That opens React Native DevTools for the connected Hermes app, with React DevTools, the JavaScript console, sources, network, and memory panels.

React Native DevTools attaches to one app at a time. If another debugger or a CDP client is attached, close it before opening DevTools again.

SEO Preview

See how your page appears in Google search results and check for common SEO issues:

Route Info

Debug the current route state:

Loader Timing

Visualize loader performance with a waterfall breakdown:

Useful for identifying slow loaders and optimizing data fetching.

Errors

Track errors from error boundaries and loaders:

Errors are collected in real-time so you can see issues as they happen.

Source Inspector

The inspector is injected automatically in development when devtools.inspector is enabled (the default). It works through the data-one-source attribute One adds to components during development. Hold Option (Mac) or Alt (Windows/Linux) for 0.8 seconds and hover over any element to see its source location highlighted. Click to open a picker showing:

Files open in the editor configured via devtools.editor, or the LAUNCH_EDITOR / EDITOR environment variable.

SourceInspector component

one also exports a SourceInspector component with its props type, kept for backwards compatibility:

import { SourceInspector } from 'one'
// deprecated: the inspector above is injected automatically.
// this component renders nothing. remove it for cleaner code.
export function Layout() {
return <SourceInspector />
}

SourceInspectorProps accepts hotkey and enabled, but both are deprecated: the activation key and enabled state now come from the injected devtools script and the devtools.inspector config.

Input Recording

Record user interactions for bug reports or AI-assisted debugging. Start recording from:

After a 2-second countdown, recording begins. Tap Option to stop and copy the log to clipboard.

The output is a compact, line-based format optimized for AI consumption:

00.000Z
# https://localhost:3000/dashboard
# components: Button < Card < Dashboard
# selector: [data-testid="submit-btn"]
# window: 1920x1080 scroll:0,0
# duration: 3200ms events: 28
0 click 450,320 btn:0 [#submit] @Button.tsx:15 "Submit"
85 keydown Tab
142 focus [input.email]
200 input val:"test@" [input.email]
# final hover: [.sidebar > nav]
# final source: Nav.tsx:42:5

Events captured include clicks, keyboard input, scroll, focus/blur, input changes, wheel, resize, and more.

Panel Features

The dev tools panel is:

Extending the web panel

A plugin is a module that default exports a OneDevtoolsPlugin. Use the defineDevtoolsPlugin helper so the editor checks the shape:

devtools/runtime-inspector.ts
import { defineDevtoolsPlugin } from 'one/devtools'
export default defineDevtoolsPlugin({
name: 'runtime-inspector',
title: 'Runtime Inspector',
category: 'Tuning',
// An iframe keeps a devtool that already runs its own UI and server as-is.
panel: {
url: 'http://localhost:4577',
},
actions: [
{
id: 'open-web-panel',
title: 'Open Runtime Inspector',
run() {
window.open('http://localhost:4577', '_blank')
},
},
],
})

Register it in vite.config.ts:

import { one } from 'one/vite'
export default {
plugins: [
one({
devtools: {
plugins: ['./devtools/runtime-inspector.ts'],
},
}),
],
}

Plugin modules run in the browser. They can add a panel, actions, or both:

The context exposes project, url, openPanel, and closePanel. Panel ids are namespaced as plugin:<name>. Two plugins cannot claim the same name.

Plugins are loaded only in development. The module is resolved through Vite, so local TypeScript and JSX files work without a build step.

Rozenite plugins in React Native DevTools

One hosts the Rozenite plugin convention for React Native. If a Rozenite plugin package is installed in your app, One mounts its plugin host on the native dev server and React Native DevTools shows the panels. Existing Rozenite plugins work without a Metro wrapper or a separate withRozenite config.

Terminal window
bun add -d @rozenite/storage-plugin

On the next one dev, pressing j or dt opens DevTools with the Storage panel. One logs the plugin names it found:

[one] React Native DevTools plugins: @rozenite/storage-plugin (open with dt or j)

Discovery checks direct dependencies for a Rozenite manifest (dist/rozenite.json), the same convention Rozenite’s Metro integration uses. To pin the list or exclude a plugin:

one({
devtools: {
rozenite: {
include: ['@rozenite/storage-plugin'],
exclude: ['@rozenite/network-activity-plugin'],
pluginDisplay: 'sidebar', // or 'tabs'
},
},
})

Set rozenite: false to keep the stock React Native DevTools without the Rozenite host. When no Rozenite plugin is installed, One leaves the debugger frontend untouched.

One hosts Rozenite when One’s Vite bundler serves the native app, which is the default. If you set native.bundler: 'metro', keep using Rozenite’s own withRozenite Metro wrapper instead.

The device half of a Rozenite plugin still lives in your app. Follow the plugin’s install instructions and import it once from your app entry when it asks you to.

Runtime Inspector

Runtime Inspector is the reference adapter for this API. It already ships its semantics and layouts as a protocol-first package with a Rozenite panel. In a One app:

  1. Add @runtime-inspector/react-native and @runtime-inspector/panel-rozenite to the app.
  2. Import the panel once from the app entry: import '@runtime-inspector/panel-rozenite'.
  3. Press j or dt. Runtime Inspector appears in React Native DevTools through Rozenite.

Its web panel already runs as its own server, so the web adapter is a plugin with panel: { url } like the example above. No Runtime Inspector protocol change is needed for either host.

Configuration

Dev tools are enabled by default in development mode. To disable them, set:

vite.config.ts
import { one } from 'one/vite'
export default {
plugins: [
one({
devtools: false,
}),
],
}

To keep the web tools but change individual features:

one({
devtools: {
inspector: true,
editor: 'cursor',
seoPreview: true,
// browser plugin modules for the One overlay
plugins: ['./devtools/my-panel.ts'],
// Rozenite host for React Native DevTools
rozenite: {
pluginDisplay: 'tabs',
},
},
})

Edit this page on GitHub.