Skip to content

Patches & Devtools

Immer patch streams for undo/redo and sync, plus the state inspector panel.

Every update can emit Immer patches, enabling undo/redo, sync, and the devtools. Patches are only computed when there’s a consumer, so the common path stays allocation-free.

import { applyPatchesToStore } from "@nice-code/state";
// Listen to patches for every update
const stop = store.listenToPatches((patches, inversePatches) => {
sendToServer(patches);
});
// Or collect patches for a single update
store.update((s) => { s.count += 1; }, (patches, inverse) => {
undoStack.push(inverse);
});
// Apply patches (received from elsewhere, or to undo)
store.applyPatches(patches);

Inverse patches are the foundation of undo: keep a stack of them and applyPatches the top entry to revert.

A zero-config inspector for your stores — a timeline of changes, before/after diffs, a live state inspector with direct editing, and patch-based revert. Import the panel from @nice-code/state/devtools/browser.

// devtools.ts — register the stores you want to observe
import { StateDevtoolsCore } from "@nice-code/state/devtools/browser";
import { counterStore } from "./counterStore";
export const stateDevtools = new StateDevtoolsCore();
stateDevtools.registerStore("counterStore", counterStore);
// Mount once near your app root. Renders nothing in production
// (NODE_ENV !== "development").
import { NiceStateDevtools } from "@nice-code/state/devtools/browser";
import { stateDevtools } from "./devtools";
<NiceStateDevtools core={stateDevtools} position="dock-bottom" />

position is one of "dock-bottom" | "dock-top" | "dock-left" | "dock-right". The panel lets you filter by store, inspect and edit live state, view per-change diffs and patches, pause the timeline, and revert a change via its inverse patches.

Registering a store attaches a patch listener (a negligible dev-time cost). Keep devtools setup out of production bundles.

EntryContents
@nice-code/stateStore, update, applyPatchesToStore, core types
@nice-code/state/reactuseStoreState, useLocalStore, InjectStoreState
@nice-code/state/devtools/browserStateDevtoolsCore, NiceStateDevtools