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-toggleBoth 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
| Mode | What it paints |
|---|---|
off | No overlay; data-source attributes cleared. |
highlight-visor | Mint outline + 30% mint background on every Visor-sourced element. |
highlight-non-visor | Coral 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 “”.