Skip to content

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

tsx
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:

  1. The counter updates in your UI
  2. The DevTool popup shows the new value instantly
  3. 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:

tsx
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:

tsx
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:

tsx
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:

tsx
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:

tsx
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:

tsx
{
  process.env.NODE_ENV === "development" && (
    <DevTool name="Counter" item={sCounter} />
  );
}

Not this - DevTool always visible:

tsx
<DevTool name="Counter" item={sCounter} /> {/* This will show in production! */}

✅ Give DevTools Meaningful Names

Do this - Use descriptive names:

tsx
<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):

tsx
<DevTool name="" item={sUser} />
<DevTool name="" item={sCart} />
<DevTool name="" item={sSettings} />

✅ Organize Multiple DevTools

Do this - Group related DevTools:

tsx
{
  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:

tsx
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:

tsx
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:

tsx
<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 windows
  • item: 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:

tsx
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

  1. Always wrap with process.env.NODE_ENV === "development"
  2. Always provide a name prop - it's required for all DevTools
  3. Give meaningful names to make DevTools easier to identify
  4. Use for development only - never in production
  5. Don't overuse - too many DevTools can clutter your screen

Quick Start Reminder

tsx
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!

Released under the MIT License.