npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@polystate/devtools

v0.2.0

Published

Redux DevTools Extension middleware for Polystate

Downloads

102

Readme

@polystate/devtools

Redux DevTools Extension middleware for Polystate with time-travel debugging.

Features

  • Redux DevTools Integration: Full support for Redux DevTools Extension
  • Time-Travel Debugging: Step through action history
  • Action Inspector: View and inspect all actions and state changes
  • State Snapshots: Export and import state for debugging
  • Action History: Track action sequence and payloads
  • Zero Runtime Cost: Only active when DevTools Extension is installed

Installation

npm install @polystate/core @polystate/devtools

You also need the Redux DevTools Extension browser extension.

Quick Start

import { createStore } from '@polystate/core';
import { createDevToolsMiddleware } from '@polystate/devtools';

// Create store first (needed so DevTools can call store.setState for time-travel)
const store = createStore(
  { count: 0 },
  {
    increment: (state) => ({ ...state, count: state.count + 1 }),
  },
  {
    middleware: [
      createDevToolsMiddleware(store, {
        name: 'CounterStore',
        timeTravel: true,
        maxAge: 50,
      }),
    ],
  }
);

// Now open Redux DevTools to inspect and time-travel!

Configuration

Basic Setup

import { createDevToolsMiddleware } from '@polystate/devtools';

const store = createStore(initialState, actions, {
  middleware: [createDevToolsMiddleware()],
});

With Options

const store = createStore(initialState, actions, {
  middleware: [
    createDevToolsMiddleware({
      // Store name shown in DevTools
      name: 'MyAppStore',

      // Enable time-travel debugging
      timeTravel: true,

      // Maximum actions to keep in history
      maxAge: 50,
    }),
  ],
});

Features

Action Inspection

View all dispatched actions and their payloads:

await store.dispatch('addTodo', { text: 'Learn Polystate' });
// Shows in DevTools:
// {
//   type: 'addTodo',
//   payload: { text: 'Learn Polystate' },
//   timestamp: 1699564032450
// }

State Snapshots

Export and import state for debugging:

// Export current state in DevTools
// (Use DevTools UI: Store → Export)

// Import saved state
// (Use DevTools UI: Store → Import State)

Time-Travel Debugging

Step forward and backward through action history:

  1. Open Redux DevTools
  2. Click on any action in the history
  3. App state jumps to that point
  4. Make changes and step forward again

Store Name Configuration

createDevToolsMiddleware({
  name: 'UserStore', // Shown in DevTools dropdown
});

Multi-Store Setup

Use different names for different stores:

const userStore = createStore(userState, userActions, {
  middleware: [createDevToolsMiddleware({ name: 'UserStore' })],
});

const todoStore = createStore(todoState, todoActions, {
  middleware: [createDevToolsMiddleware({ name: 'TodoStore' })],
});

const appStore = createStore(appState, appActions, {
  middleware: [createDevToolsMiddleware({ name: 'AppStore' })],
});

Switch between stores in DevTools dropdown.

Combining with Other Middleware

import { loggerMiddleware, persistMiddleware } from '@polystate/core';
import { createDevToolsMiddleware } from '@polystate/devtools';

const store = createStore(initialState, actions, {
  middleware: [
    // Logger first (logs complete context)
    loggerMiddleware(),

    // DevTools for inspection
    createDevToolsMiddleware({ name: 'MyStore' }),

    // Persist last (fires after other middleware)
    persistMiddleware('my-app'),
  ],
});

TypeScript Example

import { createStore } from '@polystate/core';
import { createDevToolsMiddleware } from '@polystate/devtools';

interface AppState {
  count: number;
  user: { id: number; name: string } | null;
  loading: boolean;
}

const store = createStore<AppState>(
  { count: 0, user: null, loading: false },
  {
    increment: (state) => ({
      ...state,
      count: state.count + 1,
    }),
    setUser: (state, user: AppState['user']) => ({
      ...state,
      user,
    }),
    setLoading: (state, loading: boolean) => ({
      ...state,
      loading,
    }),
  },
  {
    middleware: [
      createDevToolsMiddleware({
        name: 'AppStore',
        timeTravel: true,
        maxAge: 30,
      }),
    ],
  }
);

// Dispatch with full type safety
await store.dispatch('increment');
await store.dispatch('setUser', { id: 1, name: 'Alice' });
await store.dispatch('setLoading', false);

React Integration

import { createStore } from '@polystate/core';
import { useSelector, useDispatch } from '@polystate/react';
import { createDevToolsMiddleware } from '@polystate/devtools';

const store = createStore(initialState, actions, {
  middleware: [createDevToolsMiddleware({ name: 'ReactStore' })],
});

function App() {
  const count = useSelector(store, (state) => state.count);
  const { dispatch } = useDispatch(store);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => dispatch('increment')}>+</button>
    </div>
  );
}

Angular Integration

import { Injectable } from '@angular/core';
import { createStore } from '@polystate/core';
import { PolystateService } from '@polystate/angular';
import { createDevToolsMiddleware } from '@polystate/devtools';

@Injectable({ providedIn: 'root' })
export class CounterService extends PolystateService<{ count: number }> {
  private store = createStore(
    { count: 0 },
    { increment: (state) => ({ ...state, count: state.count + 1 }) },
    {
      middleware: [createDevToolsMiddleware({ name: 'AngularStore' })],
    }
  );

  count = this.select((state) => state.count);
}

DevTools Shortcuts

After installing the Redux DevTools Extension:

  • Open DevTools: Usually F12 or Cmd+Option+I
  • Find Store: Look for the Redux tab in DevTools
  • Inspect Action: Click any action to see full details
  • Time Travel: Click any action to jump to that state
  • Dispatch Action: Use the Actions tab to dispatch manually
  • Export State: Use Store → Export State
  • Import State: Use Store → Import State

Browser Support

Works in any browser with Redux DevTools Extension installed:

  • Chrome
  • Firefox
  • Edge
  • Safari (with extension)

Performance

The middleware has minimal performance impact:

  • No overhead if DevTools Extension is not installed
  • Efficient action recording
  • Configurable history size (default: 50 actions)
  • Zero-copy state snapshots

Options Reference

interface DevToolsConfig {
  /**
   * Store name for DevTools UI
   * @default "Polystate Store"
   */
  name?: string;

  /**
   * Enable time-travel debugging
   * @default true
   */
  timeTravel?: boolean;

  /**
   * Maximum number of actions to keep in history
   * @default 50
   */
  maxAge?: number;
}

Troubleshooting

DevTools not showing actions

  1. Install Redux DevTools Extension
  2. Open DevTools (F12)
  3. Click "Redux" tab (might be under ">>" icons)
  4. Make sure Polystate store is selected in dropdown

Actions not time-traveling

Check that timeTravel: true is set in config:

createDevToolsMiddleware({
  name: 'MyStore',
  timeTravel: true, // ← Add this
});

Too many actions in history

Reduce maxAge:

createDevToolsMiddleware({
  name: 'MyStore',
  maxAge: 20, // Keep only last 20 actions
});

API Reference

createDevToolsMiddleware

function createDevToolsMiddleware<T>(config?: DevToolsConfig): Middleware<T>;

Creates DevTools middleware for a store.

Parameters:

  • config - Optional configuration object

Returns: Middleware function

Example:

const middleware = createDevToolsMiddleware({ name: 'AppStore' });

connectDevTools

function connectDevTools<T>(store: Store<T>, config?: DevToolsConfig): Store<T>;

Connect an existing store to DevTools (if not already connected).

exportStateHistory

function exportStateHistory(store: Store<any>): Array<{ action: string; state: any }>;

Export the action/state history.

importStateHistory

function importStateHistory(
  store: Store<any>,
  history: Array<{ action: string; state: any }>
): void;

Import a previously exported history.

Advanced Use Cases

Conditional DevTools

const middleware = [];

if (process.env.NODE_ENV === 'development') {
  middleware.push(createDevToolsMiddleware({ name: 'AppStore' }));
}

const store = createStore(initialState, actions, { middleware });

Multiple Stores with DevTools

const userStore = createStore(userState, userActions, {
  middleware: [createDevToolsMiddleware({ name: 'Users' })],
});

const todoStore = createStore(todoState, todoActions, {
  middleware: [createDevToolsMiddleware({ name: 'Todos' })],
});

const settingsStore = createStore(settingsState, settingsActions, {
  middleware: [createDevToolsMiddleware({ name: 'Settings' })],
});

Switch between them in DevTools to debug each independently.

Contributing

See CONTRIBUTING.md

License

MIT