VisorVisor
Devtools

SourceInspector

Borealis pre-flight x-ray overlay. Walks the React Fiber tree, classifies each rendered DOM node by source file, and tints regions to surface Visor coverage and gaps.

SourceInspector is a development-only overlay that turns Borealis pre-flight from a discipline ("did I check Visor first?") into an instrument ("the screen is mostly red — file VI- tickets for those regions"). It walks the React Fiber tree post-render, resolves the source URL of each element's owning component (via _debugOwner._debugStack on React 19+, falling back to _debugSource.fileName on older runtimes), and stamps the corresponding DOM element with data-source="visor" | "local" | "third-party" | "dom". CSS rules paint outlines and tinted backgrounds for the active mode.

The component is a no-op in production builds (NODE_ENV === 'production'). Tree-shaking is guaranteed by the copy-and-own model: apps that do not run npx visor add source-inspector never include it.

Installation

npx visor add source-inspector
npx visor add source-inspector-toggle

Both files are devtools — they live under components/devtools/source-inspector/ rather than components/ui/.

Mount

Mount SourceInspector once near the app root and SourceInspectorToggle anywhere in development chrome (e.g., inside ThemeSwitcher's extras slot):

import { SourceInspector } from '@/components/devtools/source-inspector/source-inspector';
import { SourceInspectorToggle } from '@/components/devtools/source-inspector/source-inspector-toggle';
import { ThemeSwitcher } from '@/components/ui/theme-switcher/theme-switcher';

export function App({ children }) {
  return (
    <>
      <SourceInspector />
      {children}
      <ThemeSwitcher extras={<SourceInspectorToggle />} />
    </>
  );
}

The toggle mounts a default <SourceInspector> (provider + runner) lazily if none is in scope — it can be used standalone and the overlay will apply correctly without explicit wiring.

Modes

ModeWhat it paints
offNo overlay; data-source attributes cleared.
highlight-visorMint outline + 30% mint background on every Visor-sourced element.
highlight-non-visorCoral outline + 30% coral background on every locally-sourced element. This is the workhorse pre-flight mode.

Click the toggle button or press Ctrl+Shift+X to cycle. Override the hotkey via the hotkey prop on SourceInspector (e.g., hotkey="ctrl+shift+i"), or pass null to disable.

Classifiers

A classifier is a predicate over the source identifier — a file path on older React runtimes, a bundler chunk URL on React 19+ (Webpack or Turbopack). The defaults match Visor's package layout in either form:

const DEFAULT_CLASSIFIERS = {
  // Matches `@loworbitstudio/visor` (file paths, Webpack chunks) and
  // `loworbitstudio_visor` (Turbopack underscore-mangled chunk names).
  visor: (source) =>
    source.includes('@loworbitstudio/visor') ||
    source.includes('loworbitstudio_visor'),
  local: (source) => !source.includes('node_modules'),
  thirdParty: (source) =>
    source.includes('node_modules') &&
    !source.includes('@loworbitstudio/visor') &&
    !source.includes('loworbitstudio_visor'),
};

Override them when the host has a non-standard layout (monorepo with workspace packages, custom registry path, etc.):

<SourceInspector
  classifiers={{
    visor: (path) =>
      path.includes('packages/visor-components') ||
      path.includes('node_modules/@loworbitstudio/visor'),
    local: (path) => path.startsWith('/Users/me/work/my-app/src/'),
  }}
/>

The classifier order is fixed: visor wins, then local, then thirdParty, then dom for any DOM node whose owning fiber has no debug source.

Why per-element, not per-tree

Detection runs on every DOM element, not on whole component subtrees. A local component that composes Visor primitives renders with mixed regions: the wrapper (local) shows red, but its Button children (visor) show mint. That is the desired behavior — it surfaces exactly the seams where bespoke markup wraps shared primitives.

React 19 / Next 16 notes

The classifier reads fiber._debugOwner._debugStack (an Error captured by React's JSX dev runtime), parses its first user-source frame, and feeds that URL to the classifier. Production builds strip _debugStack, so the inspector renders no overlay there — same null-safe behavior the production no-op already guarantees. The component never throws on missing fields.

SourceInspector props

No props data available for “”.

SourceInspectorToggle props

No props data available for “”.