The Lab · Content
The Undo Button Every RAXXO Tool Ships With
Every RAXXO tool gives destructive actions a five-second undo window before the action becomes permanent, built once and shared everywhere.
Each line jumps to its section
- Every destructive action across all five RAXXO tools gets the same five-second undo window before it becomes permanent
- The pattern needed one shared snippet, not five separate implementations, to stay consistent
- It runs on a soft-delete queue instead of a database trigger, so undo still works offline
- It is the cheapest trust signal I ship, one toast that tells someone the tool has their back
The Moment I Realized Delete Needed a Second Chance
I was testing a cleanup feature in one of the RAXXO tools, the kind of feature that clears out old entries you no longer need. I hit delete on the wrong row. Not a big deal in a spreadsheet, where a quick Ctrl+Z brings it right back. But this was not a spreadsheet. It was a web tool talking to a database, and the row was gone the instant I clicked. No confirmation dialog would have saved me either, because I would have clicked through that just as fast. I had already decided, in my head, that I was deleting the right thing. The problem was not my confidence, it was that the tool trusted my confidence completely and had no way to walk it back.
That single click is what pushed undo from "nice idea" to "non-negotiable feature" across every RAXXO product. I had already shipped the kill switch every RAXXO tool ships with, the big red button that stops a tool from doing something catastrophic and irreversible. Undo is the small, quiet cousin of that same instinct. A kill switch stops the tool before it does the big wrong thing. Undo gives you a way back after you have already done the small wrong thing. Both exist because I do not trust any interface, including my own, to always be operated by someone paying full attention. People click fast. People click on autopilot. A tool that punishes that with permanent loss is a tool that will eventually cost someone real work, and that person will remember which tool did it to them.
Once I framed it that way, the question stopped being whether to build undo and became how to build it once and have it show up everywhere, consistently, without turning into five different half-finished versions of the same idea.
I also had to sit with an uncomfortable admission: I had been treating confirmation dialogs as if they solved this problem, and they do not. A dialog asking "are you sure" only protects against a decision you have not made yet. The moment you have already decided, the dialog becomes a formality you click through without reading, the same way most people click through a cookie notice without reading a word of it. Undo protects against a different failure mode entirely, the decision you made correctly in general but got wrong in the specific instant, the right action applied to the wrong row. No amount of asking "are you sure" catches that, because in that instant you were sure. Only a way back after the fact catches it.
What Undo Actually Covers, and What It Does Not
Undo is not a general time machine. I scoped it narrowly on purpose, to actions that are both destructive and reversible in principle: deleting a saved item, discarding a draft, removing a connection, clearing a list. Anything where the underlying data still technically exists somewhere and could be restored without touching anything else. That rules out a lot of things people might expect undo to cover, and I decided early that a narrow, reliable undo beats a broad, unreliable one.
It does not cover actions with external side effects that already left the building, like an email that already sent or a webhook that already fired. Once something has left the tool and touched another system, pretending to undo it would be dishonest, a fake button that gives false confidence. It also does not cover account-level actions like closing a subscription, because those already go through their own explicit confirmation step, not a quiet toast in the corner.
The scope I settled on is simple: if the action only changes what is stored inside the tool, and nothing has left the building yet, it gets undo. If it has already left, it gets a confirmation step instead, and the two patterns never mix on the same action. Mixing them is how you end up with a button that sometimes lies about what it can take back, and a user who stops trusting either one. I would rather have fewer things be undoable and have every single one of them actually work than promise a universal undo I cannot honor in every case.
Drawing that line also forced me to be honest about a category I initially wanted to include: actions that trigger a background job, like a re-render or an export. My first instinct was to let those be undoable too, cancel the job and pretend it never started. In practice that meant a window where the job might already be halfway done, and canceling it midway left partial files behind more often than it left a clean slate. Rather than ship an undo that sometimes worked cleanly and sometimes left debris, I moved those actions behind a plain confirmation step instead, before the job starts rather than after. Undo only earns its place where reversing it is actually guaranteed, not merely likely.
Building It Once So Five Tools Do Not Drift
The first version of this lived inside a single tool, written for that tool's specific delete flow. It worked, but it was not reusable, and I already knew from the shared snippet that almost broke three RAXXO tools at once how badly small inconsistencies compound once you are running several products from one codebase. If I rebuilt undo by hand in each tool, I would get five slightly different timing windows, five slightly different toast styles, and eventually a support conversation where someone describes a pattern in one tool that simply does not exist in another.
So I pulled it out into one shared piece: a small queue that holds a soft-deleted item, a countdown, and a toast component that shows the same way in every tool, using the same undo verb, the same position on screen, the same motion when it appears and disappears. Any tool that needs undo calls the same function with the same three arguments: what got removed, how to restore it, and what label to show. The tool does not get to reinvent the wording or the timing. That constraint is the whole point. Consistency across five products is not a nice-to-have, it is what lets someone learn the pattern once in whichever RAXXO tool they met first and carry that knowledge into every other one without a second thought.
Under the hood, nothing is actually deleted the moment you click. The item gets flagged and moved into a holding queue instead of being removed outright. If the countdown finishes without an undo, the queue processes the real removal. If you click undo, the flag clears and the item goes back exactly where it was, no reconstruction needed because nothing was ever thrown away in the first place. That queue lives in the same local state the tool already uses, which is what makes undo keep working even if your connection drops for a moment. The countdown is just a timer, not a network call, so a shaky connection cannot silently eat your undo window.
The Five-Second Choice
Five seconds sounds like an arbitrary number until you actually sit and time how people react to a toast appearing at the bottom of a screen. Too short, under three seconds, and the window closes before someone has even registered that the action happened, let alone decided they wanted it back. Too long, past eight or nine seconds, and the toast stops feeling urgent. It becomes background furniture, something you learn to ignore the same way you learn to ignore a cookie banner. Five seconds sits in the spot where the toast is still fresh in your peripheral vision when it fades, long enough to react, short enough to still feel immediate.
I picked that number the same way I picked the toast timeout used everywhere else in the RAXXO design system, by testing it on myself first across ordinary use, not by running a formal study. That is consistent with how I ship most interface details, described in the empty state every RAXXO tool needs before I call it shipped: small, specific decisions made once, tested by actually using the product the way a customer would, then locked in everywhere so nobody has to relitigate them tool by tool.
There is a second reason five seconds works well beyond the psychology of it. It is short enough that the soft-delete queue never grows large. An item sits in limbo for at most five seconds before it either comes back or actually goes away, which keeps the whole system simple. I did not need a cleanup job, an expiry cron, or a background process quietly sweeping old queued deletions. The countdown itself is the cleanup mechanism. Picking a small, fixed window turned what could have been a small infrastructure problem into something that resolves itself every single time, five seconds after it starts.
Bottom Line
Undo is one of those features that costs almost nothing to explain and almost nothing to notice when it works. Nobody writes in to say thank you for the toast that let them get a deleted item back. They just quietly do not lose the thing they were working on, and the moment passes without becoming a support ticket or a frustrated close of the tab. That invisibility is exactly what makes it worth shipping everywhere, not just where I first felt the pain of missing it.
Building it as one shared piece instead of five separate ones was the part that actually mattered. The five-second window, the soft-delete queue, the consistent toast, none of it matters if only one of the five tools has it. What makes undo a real trust signal instead of a nice feature in a single product is that it behaves the same way no matter which RAXXO tool you happen to be using that day. That consistency is the actual product decision here, the countdown timer is just the implementation detail that makes it possible.