Quick Start
Let's get React Dev Debugger working in your app in just 2 minutes! ⚡
Option 1: Zero-Config Setup (Recommended)
The absolute fastest way to get started is with zero configuration:
Step 1: Add a Single Import
Open your app's entry point (usually src/index.tsx, src/main.tsx, or src/App.tsx) and add this import at the very top:
import 'react-dev-debugger/dev';
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')!).render(<App />);
Step 2: Start Your App
Run your development server:
npm run dev
# or
npm start
Step 3: See the Magic ✨
That's it! You'll now see the React Dev Debugger panel in the bottom-right corner of your app:
Option 2: Manual Setup with Tracked Hooks
For more control and better debugging labels, use tracked hooks in your components:
Replace useState
import { useTrackedState } from 'react-dev-debugger';
function Counter() {
// Before: const [count, setCount] = useState(0);
// After: ↓
const [count, setCount] = useTrackedState(0, 'counter');
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</div>
);
}
Replace useReducer
import { useTrackedReducer } from 'react-dev-debugger';
type Action =
| { type: 'ADD_TODO'; text: string }
| { type: 'TOGGLE_TODO'; id: number };
function todoReducer(state: Todo[], action: Action) {
switch (action.type) {
case 'ADD_TODO':
return [...state, { id: Date.now(), text: action.text, done: false }];
case 'TOGGLE_TODO':
return state.map(todo =>
todo.id === action.id ? { ...todo, done: !todo.done } : todo
);
default:
return state;
}
}
function TodoList() {
const [todos, dispatch] = useTrackedReducer(
todoReducer,
[],
'todos' // Debug label
);
return (
<div>
{todos.map(todo => (
<TodoItem
key={todo.id}
todo={todo}
onToggle={() => dispatch({ type: 'TOGGLE_TODO', id: todo.id })}
/>
))}
</div>
);
}
Using the Debugger Panel
Once the panel appears, you can:
1. View State Timeline
Click on any state update to see:
- Before and after values
- Timestamp of the change
- Component that triggered it
- Action type (for reducers)
2. Explore Dependency Graph
Switch to the Graph tab to see:
- Component hierarchy
- State dependencies
- Context relationships
- Visual connections
3. Time-Travel Through History
Use the time-travel controls to:
- Step back to previous states
- Step forward through history
- Jump to any specific point
- Pause tracking temporarily
4. Check Performance
View the Performance tab to identify:
- Slow rendering components
- Render counts
- Average render duration
- Performance warnings
Keyboard Shortcuts
Make your debugging faster with these shortcuts:
| Shortcut | Action |
|---|---|
Ctrl/Cmd + Shift + D | Toggle panel visibility |
← | Step back in history |
→ | Step forward in history |
Space | Pause/resume tracking |
Esc | Close inspector |
Customization
Position the Panel
Drag the panel to any corner of your screen. Your preference is saved in localStorage.
Toggle Dark Mode
The panel respects your system's color scheme by default, but you can override it in the settings.
Keyboard Shortcut Configuration
Customize keyboard shortcuts through the panel settings (gear icon).
Global API
Access the debugger programmatically:
// Get the global API
const debugger = window.__REACT_STATE_DEBUGGER__;
// Jump to a specific state
debugger.goTo(5);
// Step through history
debugger.stepBack();
debugger.stepForward();
// Export state history
const snapshot = debugger.exportSnapshot();
console.log(snapshot);
// Clear all history
debugger.clear();
TypeScript Augmentation
For TypeScript users, add this to your type declarations:
import 'react-dev-debugger';
declare global {
interface Window {
__REACT_STATE_DEBUGGER__: import('react-dev-debugger').ReactStateDebuggerAPI;
}
}
Example: Complete Counter App
Here's a complete example putting it all together:
import { useTrackedState } from 'react-dev-debugger';
function App() {
const [count, setCount] = useTrackedState(0, 'counter');
const [name, setName] = useTrackedState('', 'userName');
const handleIncrement = () => {
setCount(prev => prev + 1);
};
const handleReset = () => {
setCount(0);
setName('');
};
return (
<div style={{ padding: '2rem' }}>
<h1>React Dev Debugger Demo</h1>
<div>
<h2>Counter: {count}</h2>
<button onClick={handleIncrement}>
Increment
</button>
<button onClick={() => setCount(count - 1)}>
Decrement
</button>
</div>
<div>
<h2>Name: {name || '(empty)'}</h2>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Enter your name"
/>
</div>
<button onClick={handleReset}>
Reset All
</button>
</div>
);
}
export default App;
import 'react-dev-debugger/dev';
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
What's Next?
- 📚 Check out Comprehensive Examples for real-world use cases
- 🔧 Learn about Store Adapters for Redux, Zustand, etc.
- 📖 Explore the Full API Reference
- ⚡ Read Performance Tips for optimization
Need help? Join our GitHub Discussions!