Creating Plugins
Extend React Trace by building your own plugins. A plugin is a TracePlugin object with a name and optional React components for the widget's toolbar, actionPanel, and settings slots.
Scaffolding
The fastest way to start is with the scaffolding CLI:
This generates a complete plugin package with build config, production stubs, and optional toolbar/action-panel/settings scaffolding. The CLI prompts for a plugin name, description, and which slots to scaffold.
The TracePlugin interface
Slots
toolbar— renders directly inside the core toolbar. Use this for persistent controls like toggle buttons or status badges.actionPanel— renders inside the selected-component action menu. Use this for actions that operate on the currently inspected element.settings— renders inside the widget settings popover. Use this for plugin configuration UI.
Plugin components receive no props. Read shared state through the hooks below.
Minimal example
Hooks
All hooks are exported from @react-trace/core.
useProjectRoot()
Returns the current project root string passed to <Trace root="..." />.
useInspectorActive()
Returns true when inspector mode is currently active (the user is hovering to select elements).
useDeactivateInspector()
Returns a callback that turns inspector mode off. Call this before opening plugin-owned interactive UI (like a modal or form) to prevent the inspector from capturing clicks.
useSelectedContext()
Returns the currently selected ComponentContext | null. This is the primary hook for reading what the user has inspected.
useClearSelectedContext()
Returns a callback that clears the current selection. Use this when a plugin flow should dismiss the current inspection.
useSelectedSource()
Returns the currently selected ComponentSource | null. Each source includes source-mapped file coordinates and pre-computed project-relative and absolute paths.
useWidgetPortalContainer()
Returns the widget portal container element. Use this for popovers, dropdowns, tooltips, and other portal-mounted UI so they render inside the widget shell instead of document.body.
Utilities and constants
Types
All types are exported from @react-trace/core:
Production stubs
When adding a new public export to your plugin, mirror it in src/index.prod.ts:
- Components — export a function returning
null - Hooks — export a function returning the appropriate default
- Types — re-export with
export type - Plugin factories — export a function returning
{ name: '...' }
This ensures production builds never pull in the development implementation. See Production Stubs for more details.
Tips
- Use
useWidgetPortalContainer()for all portal UI so it stays inside the widget shell. - Call
useDeactivateInspector()before opening interactive plugin UI to prevent click conflicts. - Use
@react-trace/ui-componentsfor UI primitives that match the widget's look and feel. - Keep styling inline with
styleprops — the widget uses inline styles exclusively, no CSS classes.