Browser DevTools-style inspectors for React applications to display JavaScript objects, tables, and DOM nodes.
—
The Inspector component serves as a universal interface that automatically selects the appropriate inspector type based on the provided data. It provides a single, convenient entry point for most inspection needs.
Main universal component that automatically routes to the appropriate inspector based on data type and props.
/**
* Universal inspector component that automatically selects inspector type
* @param props - Inspector configuration props
* @returns React element with appropriate inspector (Object, Table, or DOM)
*/
function Inspector(props: InspectorProps): React.ReactElement;
interface InspectorProps {
/** Data to inspect - any JavaScript value */
data: any;
/** When true, forces TableInspector regardless of data type */
table?: boolean;
/** Theme configuration - preset string or custom theme object */
theme?: string | ThemeObject;
// ObjectInspector-specific props (when table=false or auto-selected)
/** Optional root node name */
name?: string;
/** Initial expansion level for ObjectInspector */
expandLevel?: number;
/** Paths to expand on initialization */
expandPaths?: string | string[];
/** Show non-enumerable properties */
showNonenumerable?: boolean;
/** Sort object keys */
sortObjectKeys?: boolean | ((a: string, b: string) => number);
/** Custom node renderer function */
nodeRenderer?: (props: NodeRendererProps) => React.ReactElement;
// TableInspector-specific props (when table=true)
/** Column names for TableInspector */
columns?: string[];
}The Inspector component uses the following logic to determine which inspector to use:
table={true} → TableInspectorDOMInspectorObjectInspectorimport React from "react";
import { Inspector } from "react-inspector";
// Automatic selection examples
const data = { name: "Alice", age: 30 };
const arrayData = [{ id: 1 }, { id: 2 }];
const domNode = document.getElementById("myDiv");
function AutoSelectionExamples() {
return (
<div>
{/* Uses ObjectInspector (object data) */}
<Inspector data={data} />
{/* Uses ObjectInspector (array data, but table=false) */}
<Inspector data={arrayData} />
{/* Uses TableInspector (table=true forces table mode) */}
<Inspector data={arrayData} table={true} />
{/* Uses DOMInspector (DOM node detected) */}
<Inspector data={domNode} />
</div>
);
}The Inspector component intelligently passes props to the selected inspector:
Common Props (passed to all inspectors):
datathemeObjectInspector Props (passed when ObjectInspector is selected):
nameexpandLevelexpandPathsshowNonenumerablesortObjectKeysnodeRendererTableInspector Props (passed when TableInspector is selected):
columnsDOMInspector Props (passed when DOMInspector is selected):
nameexpandLevelexpandPaths// Props are automatically routed to the correct inspector
function SmartPropsExample() {
return (
<div>
{/* ObjectInspector receives expandLevel, sortObjectKeys */}
<Inspector
data={{ z: 1, a: 2, b: 3 }}
expandLevel={1}
sortObjectKeys={true}
columns={["irrelevant"]} // Ignored for ObjectInspector
/>
{/* TableInspector receives columns */}
<Inspector
data={[{ name: "Alice" }, { name: "Bob" }]}
table={true}
columns={["name"]}
expandLevel={2} // Ignored for TableInspector
/>
</div>
);
}The Inspector uses the is-dom library to detect DOM nodes and automatically switch to DOMInspector.
DOM Node Types Detected:
function DOMDetectionExample() {
const element = document.createElement("div");
element.innerHTML = "<span>Hello</span>";
element.setAttribute("class", "example");
return (
<div>
{/* Automatically uses DOMInspector */}
<Inspector data={element} />
{/* Can still override with table=true */}
<Inspector data={element} table={true} />
</div>
);
}Common patterns for using the universal Inspector:
Quick Debugging:
// Drop-in replacement for console.log
function debug(value: any, label?: string) {
return <Inspector data={value} name={label} expandLevel={1} />;
}Conditional Display:
function ConditionalExample({ data, showAsTable }: { data: any, showAsTable: boolean }) {
return (
<Inspector
data={data}
table={showAsTable}
expandLevel={showAsTable ? undefined : 1}
columns={showAsTable ? ["name", "value"] : undefined}
/>
);
}Multi-format Data Viewer:
function DataViewer({ data }: { data: any }) {
const [viewMode, setViewMode] = useState<'auto' | 'table' | 'object'>('auto');
const getInspectorProps = () => {
switch (viewMode) {
case 'table':
return { table: true };
case 'object':
return { table: false, expandLevel: 1 };
default:
return {}; // Auto-detect
}
};
return (
<div>
<select onChange={(e) => setViewMode(e.target.value as any)}>
<option value="auto">Auto</option>
<option value="table">Table</option>
<option value="object">Object</option>
</select>
<Inspector data={data} {...getInspectorProps()} />
</div>
);
}The Inspector component maintains type safety through union types that ensure only valid prop combinations are accepted:
type InspectorProps = TableInspectorProps | ObjectInspectorProps;
interface TableInspectorProps extends ComponentProps<typeof TableInspector> {
table: true;
}
interface ObjectInspectorProps extends ComponentProps<typeof ObjectInspector> {
table?: false;
}This ensures that TypeScript will catch invalid prop combinations at compile time:
// ✅ Valid - table mode with columns
<Inspector data={data} table={true} columns={["name"]} />
// ✅ Valid - object mode with expand level
<Inspector data={data} expandLevel={2} />
// ❌ TypeScript error - conflicting props
<Inspector data={data} table={true} expandLevel={2} />The Inspector component has minimal overhead since it simply routes to the appropriate inspector:
is-domFor performance-critical applications, consider using the specific inspector components directly if the data type is known at compile time.
Install with Tessl CLI
npx tessl i tessl/npm-react-inspector