react-state-inspector-devtools
v1.2.0
Published
Core registry and hooks for React State Inspector
Readme
react-state-inspector-devtools
A lightweight, runtime state inspector for React.
Inspect and edit component state live — directly from your app.
✨ What is this?
react-state-inspector-devtools is a dev-only React tool that lets you:
- 👀 See which components are currently mounted
- 🔍 Inspect their internal state (
useState) - ✏️ Edit state values live from a floating UI panel
- ⚡ Observe UI updates instantly
No browser extensions.
No React DevTools dependency.
Just drop it into your app.
🧠 Why?
React DevTools are great — but sometimes you want:
- 🖥️ State inspection inside the app
- 🧪 A tool that works in embedded environments, previews, sandboxes
- 🎨 A way to poke state values quickly while designing UI
- ⚙️ Zero setup, zero configuration
This tool is optimized for developer experience, not production analytics.
📦 Installation
npm install react-state-inspector-devtoolsor
pnpm add react-state-inspector-devtoolsor
yarn add react-state-inspector-devtools🚀 Quick Start
1️⃣ Wrap your app with the provider (dev-only)
import { StateInspectorProvider, StateInspectorUI } from "react-state-inspector-devtools";
export function AppRoot() {
return (
<StateInspectorProvider enabled={import.meta.env.DEV}>
<App />
{import.meta.env.DEV && <StateInspectorUI />}
</StateInspectorProvider>
);
}⚠️ Important:
This tool is intended for development only.
Always gate it behindDEV/NODE_ENV !== "production".
2️⃣ Opt-in to state inspection
Replace useState with useInspectableState:
import { useInspectorComponent, useInspectableState } from "react-state-inspector-devtools";
export function CounterCard() {
const inspector = useInspectorComponent("CounterCard");
const [count, setCount] = useInspectableState(inspector, "count", 0, {
type: "number",
min: 0,
max: 999,
step: 1,
});
return (
<div>
<button onClick={() => setCount((c) => c - 1)}>-</button>
<span>{count}</span>
<button onClick={() => setCount((c) => c + 1)}>+</button>
</div>
);
}That's it.
The component and its state will appear in the inspector UI.
🪟 The Inspector UI
- Appears as a floating button in the bottom-right corner
- Opens a panel with:
- Left: Mounted components list
- Right: Editable state values
- State changes update the UI immediately
Supported Editors
| Type | Editor |
| --------- | ---------------------------------- |
| boolean | ✅ Checkbox |
| number | ✅ Number input (min / max / step) |
| text | ✅ Text input (with placeholder) |
| select | ✅ Dropdown |
| json | ✅ JSON editor |
🧩 API Reference
StateInspectorProvider
Wraps your app and controls whether the inspector is active.
<StateInspectorProvider enabled={boolean}>{children}</StateInspectorProvider>| Prop | Type | Description |
| ---------- | ----------- | ---------------------------------------- |
| enabled | boolean | Controls whether the inspector is active |
| children | ReactNode | Your application |
StateInspectorUI
Renders the floating inspector overlay.
<StateInspectorUI />useInspectorComponent(label?: string)
Registers a component instance with the inspector.
const inspector = useInspectorComponent("ProfileForm");- Creates a stable component identity
- Must be called once per component
- The
labelappears in the component list
useInspectableState<T>(inspector, key, initialValue, meta?)
Drop-in replacement for useState that registers state with the inspector.
const [value, setValue] = useInspectableState(
inspector,
key,
initialValue,
meta?
);| Parameter | Type | Description |
| -------------- | ----------------------- | ---------------------------------------- |
| inspector | InspectorComponentRef | Returned from useInspectorComponent |
| key | string | State name shown in the UI |
| initialValue | T | Initial state value (same as useState) |
| meta | InspectableMeta | Optional UI hints for the editor |
📝 Meta Options
The meta parameter controls how the state is rendered in the inspector UI:
Boolean
{
type: "boolean";
}Number
{ type: "number", min: 0, max: 100, step: 5 }Text
{ type: "text", placeholder: "Enter name..." }Select (Dropdown)
{
type: "select",
options: ["small", "medium", "large"],
}
// Or with labels
{
type: "select",
options: [
{ label: "Small", value: "sm" },
{ label: "Medium", value: "md" },
{ label: "Large", value: "lg" },
],
}JSON
{
type: "json";
}💡 Tip: If you don't provide
meta, the type is automatically inferred from the initial value.
🧪 Examples
Boolean Flags
export function FlagsPanel() {
const inspector = useInspectorComponent("FlagsPanel");
const [isAdmin, setIsAdmin] = useInspectableState(inspector, "isAdmin", false, {
type: "boolean",
});
const [betaUser, setBetaUser] = useInspectableState(inspector, "betaUser", true, {
type: "boolean",
});
return (
<div>
<label>
<input type="checkbox" checked={isAdmin} onChange={(e) => setIsAdmin(e.target.checked)} />
Is Admin
</label>
<label>
<input type="checkbox" checked={betaUser} onChange={(e) => setBetaUser(e.target.checked)} />
Beta User
</label>
</div>
);
}Select Dropdown
export function VariantPicker() {
const inspector = useInspectorComponent("VariantPicker");
const [variant, setVariant] = useInspectableState(inspector, "variant", "M", {
type: "select",
options: ["S", "M", "L", "XL"],
});
return (
<select value={variant} onChange={(e) => setVariant(e.target.value)}>
{["S", "M", "L", "XL"].map((v) => (
<option key={v} value={v}>
{v}
</option>
))}
</select>
);
}Text Inputs
export function ProfileForm() {
const inspector = useInspectorComponent("ProfileForm");
const [name, setName] = useInspectableState(inspector, "name", "", {
type: "text",
placeholder: "Name",
});
const [email, setEmail] = useInspectableState(inspector, "email", "", {
type: "text",
placeholder: "Email",
});
return (
<div>
<input value={name} onChange={(e) => setName(e.target.value)} placeholder="Name" />
<input value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Email" />
</div>
);
}🔒 Production Safety
- ✅ The inspector does nothing when
enabled={false} - ✅ No side effects, no global patches
- ✅ No state is tracked unless you opt in
⚠️ Still, do not ship it enabled in production.
🛠️ Use Cases
- 🎨 UI development & tweaking
- 📐 Design system work
- 📚 Component libraries
- 🖼️ Embedded previews
- 🔧 Internal tools
- 🎤 Demos & presentations
🧩 Inspired by
- React DevTools
- Redux DevTools
- In-app debug overlays
…but intentionally simpler and runtime-focused.
📄 License
MIT
⭐ Feedback
This is a V1 devtool built for real-world usage.
Ideas, issues, and PRs are welcome!
