Skip to content

Debugging & Development ​

Development tools and debugging patterns for store operations, including debug modes, performance monitoring, and state inspection utilities.

Debug Mode for Stores ​

Enable debug mode to track store value changes during development:

tsx
const debugUser = useStoreValue(userStore, undefined, {
  debug: true,
  debugName: 'UserProfile'
});

// Console output:
// [UserProfile] Store value changed: { previous: {...}, current: {...} }

Performance Monitoring ​

Monitor store performance with custom performance tracking:

tsx
const useStorePerformanceMonitor = (storeName) => {
  const [metrics, setMetrics] = useState({
    updateCount: 0,
    lastUpdate: null,
    averageUpdateInterval: 0
  });
  
  const store = useAppStore(storeName);
  
  useEffect(() => {
    const startTime = Date.now();
    let updateCount = 0;
    let lastUpdateTime = startTime;
    
    const unsubscribe = store.subscribe(() => {
      const now = Date.now();
      updateCount++;
      
      setMetrics(prev => ({
        updateCount,
        lastUpdate: now,
        averageUpdateInterval: (now - startTime) / updateCount
      }));
      
      lastUpdateTime = now;
    });
    
    return unsubscribe;
  }, [store]);
  
  return metrics;
};

// Usage
function MonitoredComponent() {
  const metrics = useStorePerformanceMonitor('user');
  
  if (process.env.NODE_ENV === 'development') {
    console.log('Store metrics:', metrics);
  }
  
  return <div>Component with monitoring</div>;
}

Store State Inspection ​

Create a debugging utility to inspect multiple stores:

tsx
const useStoreDebugger = (stores) => {
  useEffect(() => {
    if (process.env.NODE_ENV !== 'development') return;
    
    const unsubscribers = Object.entries(stores).map(([name, store]) => {
      return store.subscribe((value, previous) => {
        console.group(`🏪 Store [${name}] Updated`);
        console.log('Previous:', previous);
        console.log('Current:', value);
        console.log('Changed:', !Object.is(previous, value));
        console.groupEnd();
      });
    });
    
    return () => unsubscribers.forEach(unsub => unsub());
  }, [stores]);
};

// Usage
function DebuggedApp() {
  const userStore = useAppStore('user');
  const settingsStore = useAppStore('settings');
  
  useStoreDebugger({
    user: userStore,
    settings: settingsStore
  });
  
  return <div>App with store debugging</div>;
}

Development Tools ​

Store Value Inspector ​

tsx
const useStoreInspector = (store, enabled = process.env.NODE_ENV === 'development') => {
  useEffect(() => {
    if (!enabled) return;
    
    const unsubscribe = store.subscribe((value, previous) => {
      console.table({
        'Store': store.name || 'Unknown',
        'Previous': JSON.stringify(previous, null, 2),
        'Current': JSON.stringify(value, null, 2),
        'Timestamp': new Date().toISOString()
      });
    });
    
    return unsubscribe;
  }, [store, enabled]);
};

Performance Profiler ​

tsx
const useStoreProfiler = (stores) => {
  const [profile, setProfile] = useState({});
  
  useEffect(() => {
    if (process.env.NODE_ENV !== 'development') return;
    
    const profiler = {};
    
    const unsubscribers = Object.entries(stores).map(([name, store]) => {
      profiler[name] = {
        updates: 0,
        lastUpdate: Date.now(),
        intervals: []
      };
      
      return store.subscribe(() => {
        const now = Date.now();
        const interval = now - profiler[name].lastUpdate;
        
        profiler[name].updates++;
        profiler[name].intervals.push(interval);
        profiler[name].lastUpdate = now;
        
        // Keep only last 100 intervals
        if (profiler[name].intervals.length > 100) {
          profiler[name].intervals.shift();
        }
        
        setProfile({ ...profiler });
      });
    });
    
    return () => unsubscribers.forEach(unsub => unsub());
  }, [stores]);
  
  return profile;
};

Debugging Strategies ​

Development Workflow ​

  1. Enable Debug Mode: Use debug flags during development
  2. Monitor Performance: Track update frequencies and patterns
  3. Inspect State Changes: Log state transitions for debugging
  4. Profile Subscriptions: Identify performance bottlenecks

Production Considerations ​

  • Disable Debug Code: Ensure debug code is stripped from production
  • Conditional Logging: Use environment checks for debug output
  • Memory Monitoring: Monitor memory usage in production
  • Error Reporting: Implement error tracking for production issues

Best Practices ​

✅ Do ​

  • Use debug mode only in development environment
  • Monitor performance metrics during development
  • Create reusable debugging utilities
  • Profile subscription patterns and update frequencies

❌ Avoid ​

  • Leaving debug code enabled in production
  • Excessive logging that impacts performance
  • Debug utilities that create memory leaks
  • Performance monitoring in production without proper controls

Released under the Apache-2.0 License.