Back to Docs
Recipe

Undo / Redo UX

A command-pattern undo stack with bounded history, group transactions, and keyboard-first shortcuts — built for creative tools where every action must be reversible.

Core Pattern

Wrap every mutating operation in a Command object that implements execute() and undo(). Push executed commands onto a capped stack. On undo, pop and call undo(); push onto a redo stack. Any new action clears the redo stack — this is the standard linear undo model users expect.

Group Transactions

Batch rapid mutations (e.g., a brush stroke composed of hundreds of pointer events) into a single undo step. Open a transaction, collect child commands, then push the composite command when the transaction closes. The composite's undo() replays children in reverse.

Keyboard Shortcuts

ShortcutAction
Ctrl+ZUndo
Ctrl+Shift+ZRedo
Ctrl+YRedo (alternate)

Bounded History

Cap the undo stack at 50–100 entries. When the limit is reached, shift the oldest command off the front. This keeps memory flat regardless of session length. Persist the stack to localStorage or IndexedDB for cross-session undo if your domain warrants it.

Meridian tip: Combine undo with optimistic UI. Execute the command immediately for zero-latency feel, push to the stack, and only roll back if the server rejects the mutation. Users perceive instant responsiveness; the undo stack is your safety net.