Appearance
Time-Travel Debugging with DevTools
Quick guide to enable and use time-travel debugging with Nexus State DevTools.
Overview
Time-travel debugging allows you to:
- Navigate through your application's state history
- Revert to previous states
- Inspect how state changed over time
- Debug complex state interactions
Quick Setup
Step 1: Import Required Modules
typescript
import { atom, createStore } from '@nexus-state/core';
import { SimpleTimeTravel } from '@nexus-state/time-travel';
import { devTools } from '@nexus-state/devtools';Step 2: Create Store and TimeTravel Instance
typescript
const store = createStore();
// Create SimpleTimeTravel instance
const timeTravel = new SimpleTimeTravel(store, {
maxHistory: 50, // Maximum number of states to keep
autoCapture: true, // Automatically capture state changes
});Step 3: Apply DevTools Plugin
typescript
const devtoolsPlugin = devTools();
devtoolsPlugin.apply(store);
// DevTools will automatically find and use timeTravel from storeStep 4: Use in Your App
typescript
function App() {
const [count, setCount] = useAtom(countAtom, store);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(c => c + 1)}>+</button>
</div>
);
}How to Use Time-Travel
1. Open Redux DevTools Extension
- Install Redux DevTools (Chrome/Firefox)
- Open DevTools in your browser (F12 or Right-click → Inspect)
- Navigate to the "Nexus State" tab
2. Navigate Through History
In the DevTools interface:
- Timeline: Click on any state in the timeline to jump to it
- Jump to State: Use the slider or input to jump to a specific state
- Undo/Redo: Use the buttons to navigate through recent states
- State Inspector: View the complete state tree at any point
3. Advanced Usage
Manual Time Travel
typescript
// Jump to specific state by index
timeTravel.jumpTo(5);
// Check if undo is available
if (timeTravel.canUndo()) {
timeTravel.undo();
}
// Check if redo is available
if (timeTravel.canRedo()) {
timeTravel.redo();
}
// Get current history
const history = timeTravel.getHistory();
console.log(`History length: ${history.length}`);
// Clear history
timeTravel.clearHistory();Custom Action Names
typescript
const countAtom = atom(0, 'counter');
// Actions will be named automatically: "counter SET"
store.set(countAtom, 5);
// Or use batch for grouped actions
store.startBatch('user-update');
store.set(firstNameAtom, 'Jane');
store.set(lastNameAtom, 'Smith');
store.endBatch('user-update');
// This creates one action: "user-update"Enable Only in Development
typescript
const store = createStore();
const timeTravel = new SimpleTimeTravel(store);
if (process.env.NODE_ENV === 'development') {
const devtoolsPlugin = devTools({
name: 'My App',
maxAge: 100, // Keep more history in development
trace: true, // Capture stack traces
});
devtoolsPlugin.apply(store);
}Example: Counter with Time-Travel
typescript
import React from 'react';
import { useAtom } from '@nexus-state/react';
import { atom, createStore } from '@nexus-state/core';
import { SimpleTimeTravel } from '@nexus-state/time-travel';
import { devTools } from '@nexus-state/devtools';
const countAtom = atom(0, 'counter');
const store = createStore();
const timeTravel = new SimpleTimeTravel(store, {
maxHistory: 50,
autoCapture: true,
});
const devtoolsPlugin = devTools();
devtoolsPlugin.apply(store);
devtoolsPlugin.setTimeTravel(timeTravel); // Optional, auto-detected
function Counter() {
const [count, setCount] = useAtom(countAtom, store);
const historyLength = timeTravel.getHistory().length;
return (
<div>
<h1>Count: {count}</h1>
<p>History: {historyLength} states</p>
<button onClick={() => setCount(c => c + 1)}>Increment</button>
<button onClick={() => setCount(c => c - 1)}>Decrement</button>
<div style={{ marginTop: '20px' }}>
<h3>Time-Travel Controls:</h3>
<button onClick={() => timeTravel.undo()} disabled={!timeTravel.canUndo()}>
Undo
</button>
<button onClick={() => timeTravel.redo()} disabled={!timeTravel.canRedo()}>
Redo
</button>
</div>
</div>
);
}Troubleshooting
Time-Travel Not Working
- Ensure
SimpleTimeTravelis created with the store - Check that DevTools plugin is applied after creating timeTravel
- Verify Redux DevTools extension is installed
- Check browser console for error messages
Performance Issues
- Reduce
maxHistoryoption - Disable
autoCaptureand manually callcapture()only when needed - Use state sanitization to reduce payload size
typescript
const timeTravel = new SimpleTimeTravel(store, {
maxHistory: 20, // Keep less history
autoCapture: false, // Manual capture
});
// Manually capture at key points
timeTravel.capture('user-login');Missing States
If you don't see expected states in DevTools:
- Check that atoms are created after DevTools plugin is applied
- Verify atoms have names:
atom(0, 'myAtom') - Ensure
autoCaptureistrueor manually callcapture()
Best Practices
- Always name your atoms for better DevTools experience
- Use batch updates for related changes
- Enable time-travel only in development for production builds
- Sanitize sensitive data before sending to DevTools
typescript
const devtoolsPlugin = devTools({
stateSanitizer: (state) => {
const sanitized = { ...state };
delete sanitized.token;
delete sanitized.password;
return sanitized;
},
});