What is the Command pattern?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
The Command pattern turns an action into an object: what to do, the data it needs, and often how to undo it. Once an action is a value, you can store it, queue it, log it, replay it or reverse it.
const addItem = (item) => ({
do: (state) => [...state, item],
undo: (state) => state.filter((x) => x !== item),
label: `Add ${item.name}`,
});
What it buys you
Undo and redo, which is the classic motivation:
class History {
#done = [];
#undone = [];
run(command) {
this.state = command.do(this.state);
this.#done.push(command);
this.#undone = [];
}
undo() {
const c = this.#done.pop();
if (!c) return;
this.state = c.undo(this.state);
this.#undone.push(c);
}
}
It also gives you a queue of pending actions, a log of what happened, and the ability to retry a failed action — all because the action outlived the moment it was triggered.
Where you already use it
Redux actions are commands: a plain object describing an intent, dispatched to a handler. So are job queues, database migrations (each with up and down), and editor operations.
The trade-off
You are replacing a direct function call with an object plus a dispatcher, which is more indirection and more code. It only pays off when you need one of the capabilities above.
If all you want is to pass behaviour around, a plain function is already a first-class value in JavaScript — the ceremony of a command object adds nothing. Reach for it specifically when an action must be inspected, stored or reversed rather than simply executed.
For undo, note the hard part is usually writing a correct undo for each command, not the pattern itself. An alternative is storing snapshots of state, which is simpler but heavier.
