Time-travel debugging platform that records every state mutation across full-stack JavaScript applications and provides interactive forensic tools to investigate bugs
npm install state-surgeonTime-travel debugging platform for JavaScript applications
State Surgeon records every state mutation across your React, Redux, and Zustand applications, providing interactive forensic tools to investigate bugs.
> "Deterministic state timeline reconstruction with surgical debugging capabilities"


- ๐ฏ Automatic State Capture - Instruments React hooks, Redux stores, and Zustand without code changes
- ๐ฐ๏ธ Time Travel - Scrub through your state history with a visual timeline
- ๐ State Diff Viewer - Side-by-side comparison of before/after states
- ๐ Mutation Inspector - Detailed view of each state change with call stacks
- ๐ Causal Chain Analysis - Find the root cause of state corruption
- ๐งช Test Case Generation - Generate test cases from bug timelines (coming soon)
``bash`
npm install state-surgeon
`javascript
import { createRecorderServer } from 'state-surgeon/recorder';
const server = createRecorderServer({
port: 8080,
wsPort: 8081,
debug: true,
});
await server.start();
console.log('State Surgeon Recorder running on http://localhost:8080');
`
`javascript
import React from 'react';
import { StateSurgeonClient, instrumentReact } from 'state-surgeon/instrument';
// Create client (connects to recorder)
const client = new StateSurgeonClient({
serverUrl: 'ws://localhost:8081',
appId: 'my-app',
debug: true,
});
// Instrument React hooks
instrumentReact(React);
// Now all useState and useReducer calls are automatically tracked!
`
Open http://localhost:8080/_surgeon to see your state mutations in real-time.
`javascript
import React from 'react';
import { instrumentReact } from 'state-surgeon/instrument';
// Instrument React (call once at app startup)
const cleanup = instrumentReact(React);
// Your components work normally
function Counter() {
const [count, setCount] = React.useState(0); // โ
Automatically tracked!
return ;
}
// To stop instrumentation
cleanup();
`
`javascript
import { createStore, applyMiddleware } from 'redux';
import { createReduxMiddleware } from 'state-surgeon/instrument';
const stateSurgeonMiddleware = createReduxMiddleware({
storeName: 'main',
ignoreActions: ['@@INIT'], // Optional: ignore certain actions
});
const store = createStore(
rootReducer,
applyMiddleware(stateSurgeonMiddleware)
);
`
`javascript
import { create } from 'zustand';
import { instrumentZustand } from 'state-surgeon/instrument';
const useStore = create(
instrumentZustand(
(set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}),
{ storeName: 'counter' }
)
);
`
`javascript
import { instrumentFetch, instrumentXHR } from 'state-surgeon/instrument';
// Track all fetch calls
const cleanupFetch = instrumentFetch({
captureResponseBody: true,
ignoreUrls: ['/health', '/metrics'],
});
// Track XMLHttpRequest
const cleanupXHR = instrumentXHR();
`
#### StateSurgeonClient
Main client for connecting to the recorder server.
`typescript`
const client = new StateSurgeonClient({
serverUrl?: string; // WebSocket URL (default: 'ws://localhost:8081')
appId?: string; // Application identifier
sessionId?: string; // Session ID (auto-generated if not provided)
autoConnect?: boolean; // Connect on creation (default: true)
batchSize?: number; // Mutations to batch before sending (default: 50)
flushInterval?: number;// Flush interval in ms (default: 100)
debug?: boolean; // Enable console logging
});
#### instrumentReact(React, options?)
Patches React's useState and useReducer to capture mutations.
`typescript`
const cleanup = instrumentReact(React, {
client?: StateSurgeonClient; // Custom client instance
captureComponentName?: boolean; // Detect component from stack trace
});
#### createReduxMiddleware(options?)
Creates Redux middleware for capturing dispatched actions.
`typescript`
const middleware = createReduxMiddleware({
client?: StateSurgeonClient;
storeName?: string;
ignoreActions?: string[]; // Action types to skip
});
#### createRecorderServer(options?)
Creates the mutation recording server.
`typescript
const server = createRecorderServer({
port?: number; // HTTP port (default: 8080)
wsPort?: number; // WebSocket port (default: 8081)
cors?: boolean; // Enable CORS (default: true)
debug?: boolean; // Enable logging
});
await server.start();
`
#### StateSurgeonDashboard
React component for the forensic debugging UI.
`tsx
import { StateSurgeonDashboard } from 'state-surgeon/dashboard';
function App() {
return
}
`
`javascript
import { TimelineReconstructor } from 'state-surgeon/recorder';
const reconstructor = new TimelineReconstructor(store);
// Find exactly when a value became invalid
const corruptedMutation = await reconstructor.findStateCorruption(
sessionId,
(state) => !isNaN(state.cart?.total) // Validation function
);
console.log('State became corrupted at:', corruptedMutation);
`
`javascript
const { divergencePoint, session1Only, session2Only } =
await reconstructor.compareSessions(workingSessionId, brokenSessionId);
console.log('Sessions diverged at mutation index:', divergencePoint);
`
`javascript
const mutations = await reconstructor.findMutationsForPath(
sessionId,
'cart.total' // State path
);
console.log('These mutations affected cart.total:', mutations);
`
``
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Your Application โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ instrumentReact() โ createReduxMiddleware() โ etc. โ
โ โ โ โ
โ StateSurgeonClient โ
โ โ โ
โ WebSocket Transport โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Recorder Server โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ WebSocket Handler โ MutationStore โ API Routes โ
โ โ โ โ
โ โ โ โ
โ TimelineReconstructor โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Dashboard UI โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ TimelineScrubber โ StateDiffViewer โ MutationInspector โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
`bashInstall dependencies
npm install
MIT ยฉ 2024