DevTool Guide
What is DevTool?
DevTool is a debugging component that lets you monitor your signify values in real-time during development. Think of it as a "window" into your state that shows you exactly what's happening when values change.
Why Use DevTool?
- See changes instantly: Watch your state update live as you interact with your app
- Debug problems: Quickly spot when values aren't changing as expected
- Learn signify: Understand how signify works by seeing it in action
- Performance monitoring: Track how often your state updates
Basic Usage
Your First DevTool
import { signify } from "react-signify";
import { DevTool } from "react-signify/devtool";
const sCounter = signify(0);
function App() {
const count = sCounter.use();
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => sCounter.set(count + 1)}>+1</button>
{/* 🔧 Add DevTool - name is required */}
{process.env.NODE_ENV === "development" && (
<DevTool name="Counter" item={sCounter} />
)}
</div>
);
}
When you click the button, you'll see:
- The counter updates in your UI
- The DevTool popup shows the new value instantly
- A render counter increases each time
💡 Note: The name
prop is required for all DevTool components. It's used for the window title and saving position.
Understanding the DevTool Interface
The DevTool creates a draggable popup window with several parts:
Header (Colored Bar)
- Name & Render Count: Shows how many times the component re-rendered
- Font Size Buttons:
▲
and▼
to make text bigger/smaller - Drag Handle: Click and drag to move the window around
Content Area
- JSON Display: Shows your current value formatted nicely
- Syntax Highlighting: Different colors for strings, numbers, objects, etc.
- Scrollable: For large objects
Bottom-Right Corner
- Resize Handle: Drag to make the window bigger or smaller
Interactive Features
- Drag: Click the header to move the window
- Resize: Drag the bottom-right corner
- Remember Position: DevTool remembers where you put it between page reloads
Working with Complex Data
Objects and Arrays
DevTool works great with complex data structures:
import { DevTool } from "react-signify/devtool";
const sUser = signify({
name: "Alice",
age: 25,
preferences: { theme: "dark", language: "en" },
});
function UserProfile() {
const user = sUser.use();
return (
<div>
<h2>User: {user.name}</h2>
<button
onClick={() =>
sUser.set(({ value }) => {
value.age += 1;
})
}
>
Birthday! 🎂
</button>
{/* DevTool shows the complete object structure */}
{process.env.NODE_ENV === "development" && (
<DevTool name="User Profile" item={sUser} />
)}
</div>
);
}
Multiple DevTools
When you have several signify instances, each gets its own DevTool:
import { DevTool } from "react-signify/devtool";
const sCounter = signify(0);
const sUser = signify({ name: "Bob", score: 100 });
const sSettings = signify({ darkMode: false });
function App() {
return (
<div>
<h1>My App</h1>
<MainContent />
{/* Each signify gets its own DevTool window */}
{process.env.NODE_ENV === "development" && (
<>
<DevTool name="Counter" item={sCounter} />
<DevTool name="User Data" item={sUser} />
<DevTool name="Settings" item={sSettings} />
</>
)}
</div>
);
}
Pro tip: Each DevTool window has a different colored header so you can easily tell them apart!
Advanced Features
Custom Names for DevTools
DevTool requires a name
prop for each window. Choose meaningful names to make them easier to identify:
import { DevTool } from "react-signify/devtool";
const sCounter = signify(0);
function App() {
return (
<div>
<h1>My App</h1>
<MainContent />
{process.env.NODE_ENV === "development" && (
<DevTool name="Main Counter" item={sCounter} />
)}
</div>
);
}
Toggle DevTools On/Off
Sometimes you want to hide/show DevTools while developing:
import { DevTool } from "react-signify/devtool";
const sShowDebug = signify(false);
function App() {
const showDebug = sShowDebug.use();
return (
<div>
<h1>My App</h1>
{/* Toggle button */}
<button onClick={() => sShowDebug.set(!showDebug)}>
{showDebug ? "Hide" : "Show"} Debug Tools
</button>
<MainContent />
{/* Conditional DevTools */}
{showDebug && process.env.NODE_ENV === "development" && (
<>
<DevTool name="Counter" item={sCounter} />
<DevTool name="User Data" item={sUser} />
</>
)}
</div>
);
}
DevTool with Slices
When working with complex objects, you can create DevTools for specific parts:
import { DevTool } from "react-signify/devtool";
const sAppData = signify({
user: { name: "John", age: 25 },
settings: { theme: "light", notifications: true },
cart: [],
});
// Create slices for specific parts
const ssUser = sAppData.slice((data) => data.user);
const ssSettings = sAppData.slice((data) => data.settings);
function App() {
return (
<div>
<h1>My App</h1>
<MainContent />
{process.env.NODE_ENV === "development" && (
<>
{/* Full data */}
<DevTool name="Complete App Data" item={sAppData} />
{/* Just the user part */}
<DevTool name="User Only" item={ssUser} />
{/* Just the settings part */}
<DevTool name="Settings Only" item={ssSettings} />
</>
)}
</div>
);
}
This is helpful when you only want to monitor specific parts of large objects.
Best Practices
✅ Always Use Development Check
Do this - Wrap DevTools with environment check:
{
process.env.NODE_ENV === "development" && (
<DevTool name="Counter" item={sCounter} />
);
}
Not this - DevTool always visible:
<DevTool name="Counter" item={sCounter} /> {/* This will show in production! */}
✅ Give DevTools Meaningful Names
Do this - Use descriptive names:
<DevTool name="User Profile Data" item={sUser} />
<DevTool name="Shopping Cart Items" item={sCart} />
<DevTool name="App Settings" item={sSettings} />
Not this - No names (harder to identify):
<DevTool name="" item={sUser} />
<DevTool name="" item={sCart} />
<DevTool name="" item={sSettings} />
✅ Organize Multiple DevTools
Do this - Group related DevTools:
{
process.env.NODE_ENV === "development" && (
<div style={{ position: "fixed", top: 10, right: 10 }}>
<h4>Debug Panel</h4>
<DevTool name="Authentication" item={sAuth} />
<DevTool name="User Profile" item={sProfile} />
<DevTool name="Notifications" item={sNotifications} />
</div>
);
}
✅ Use DevTools for Learning
When learning signify, add DevTools to see how state changes:
import { DevTool } from "react-signify/devtool";
function LearningExample() {
const sCount = signify(0);
const count = sCount.use();
return (
<div>
<h2>Count: {count}</h2>
<button onClick={() => sCount.set(count + 1)}>Increment</button>
<button onClick={() => sCount.set(0)}>Reset</button>
{/* Watch how signify updates work */}
{process.env.NODE_ENV === "development" && (
<DevTool name="Learning Counter" item={sCount} />
)}
</div>
);
}
Production Considerations
⚠️ Never Ship DevTools to Production
DevTools are development-only tools. Here's how to ensure they never reach your users:
import { DevTool } from "react-signify/devtool";
// ✅ Good - Always wrap with environment check
function App() {
return (
<div>
<h1>My App</h1>
<MainContent />
{/* Only in development */}
{process.env.NODE_ENV === "development" && (
<DevTool name="Debug Counter" item={sCounter} />
)}
</div>
);
}
// ❌ Bad - DevTool always rendered
function App() {
return (
<div>
<h1>My App</h1>
<MainContent />
<DevTool name="Debug Counter" item={sCounter} />{" "}
{/* Ships to production! */}
</div>
);
}
Build-Time Removal
Most modern bundlers (Webpack, Vite, etc.) will automatically remove DevTool code when NODE_ENV=production
, so your final bundle stays clean.
No Performance Impact
When properly wrapped with environment checks:
- ✅ Zero runtime overhead in production
- ✅ No extra bundle size in production builds
- ✅ Complete removal during build process
Common Questions
Q: What props does DevTool accept?
A: DevTool accepts these props:
<DevTool
name="My Counter" // Required - window title and identification
item={sCounter} // Required - the signify instance to monitor
color="#ff6b6b" // Optional - custom header color
/>
⚠️ Important: Both name
and item
props are required. DevTool uses them for:
name
: Window title display, saving window position between page reloads, and identifying different DevTool windowsitem
: The signify instance to monitor and display state from
Q: DevTool window disappeared, how to get it back?
A: Refresh the page. DevTool remembers its position but might go off-screen if you change monitor setup.
Q: Can I use DevTools with TypeScript?
A: Absolutely! DevTools work perfectly with TypeScript and preserve all type information:
import { DevTool } from "react-signify/devtool";
interface UserData {
name: string;
age: number;
preferences: { theme: "light" | "dark" };
}
const sUser = signify<UserData>({
name: "Alice",
age: 25,
preferences: { theme: "light" },
});
// ✅ Fully typed DevTool
{
process.env.NODE_ENV === "development" && (
<DevTool name="User Profile" item={sUser} />
);
}
Summary
What DevTool Does
- Shows current state in a draggable popup window
- Updates in real-time as your signify values change
- Displays JSON with syntax highlighting for easy reading
- Tracks render count to help with performance debugging
- Remembers position between page reloads
When to Use DevTool
- 🔧 Learning signify: See how state changes work
- 🐛 Debugging issues: Spot problems with state updates
- 👥 Team collaboration: Show state to colleagues
- ⚡ Performance monitoring: Track how often components re-render
Key Rules
- Always wrap with
process.env.NODE_ENV === "development"
- Always provide a
name
prop - it's required for all DevTools - Give meaningful names to make DevTools easier to identify
- Use for development only - never in production
- Don't overuse - too many DevTools can clutter your screen
Quick Start Reminder
import { signify } from "react-signify";
import { DevTool } from "react-signify/devtool";
const sCounter = signify(0);
function App() {
const count = sCounter.use();
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => sCounter.set(count + 1)}>+1</button>
{/* Add this line to see your state in action! */}
{process.env.NODE_ENV === "development" && (
<DevTool name="Demo Counter" item={sCounter} />
)}
</div>
);
}
🎯 Next Steps: Try adding DevTool to your existing signify instances to see how your state flows through your application!