Dan North has a pattern called spike and stabilize. Instead of deciding up front whether you’re writing a throwaway prototype or production code, which means deciding at the moment you know the least, you spike to learn, then stabilize what turned out to be worth keeping. Liz Keogh has written a lot of the clearest material on it, and North’s own talk on patterns of effective delivery is where it starts.
I’ve been using it for years. It fits how I learn: make something usable, then decide what deserves more work.
In applying it, I needed more detail in two places: how to check the result, and how to keep the prototype useful as production changes. I’ve spent the last year working on both.
What a spike gives you before any of that
Two things make a spike useful to me.
You learn the codebase by building inside it. A spike that lives in the real repository has to find where the new thing plugs in, what it can reuse, and what it would break. Trying to put something new into an existing system is one of the most useful ways I’ve found to understand it. By the end I know the seams, and I know them because I hit them.
You get to use the thing. A spike makes enough of the experience work so you can walk the journey in the real product or a stand-in for it, with realistic data, at speed. That’s a different kind of knowing from a mockup. Some of the changes I make after using a spike would never have occurred to me from a static screen.
Those two are why I spike at all. The rest of this is about making what comes out of it trustworthy.
Soft spot one: “measure, don’t trust feeling”
I needed a repeatable way to compare the prototype with the implementation, beyond deciding whether the idea was worth keeping.
In my work, that comparison sometimes came down to someone senior looking at the prototype next to the production build and saying it looks right. I’ve been that someone. I’m reasonably good at it. I’ve also been wrong, and the wrongness doesn’t show up until QA, or a brand switch, or a viewport nobody checked.
So I made it mechanical. A parity gate diffs the prototype against production component by component, per interaction state. Structural components node by node, canvas-rendered ones visually at the wrapper. A change either matches the frozen answer key or it fails, loudly.
That’s the whole move: turn a principle into a gate. “It looks right” becomes “it matched, or here’s the delta.”
Soft spot two: the spike is one-shot
A prototype can be useful at the first handoff and drift out of sync by the next release. I wanted a way to keep that reference useful as the product changed.
So the spike stopped being disposable. I restructure it to mirror the production component tree one to one, one prototype fragment to one production component, indexed by a manifest, and then keep it alive. It co-evolves, release over release. A twin — not a sketch.
The manifest matters more than it sounds like it should. The mapping between prototype and production has to live somewhere other than a person’s head, so someone else can inspect it and update it when production changes.
The loop
Carve from the current build. Dial in the change on the twin. Get sign-off. Gate it. Roll up to production. Repeat.
Two rules make it work:
Carve, don’t rewrite. Cut the prototype along production’s existing component seams. Adopt them. Don’t invent better ones, however tempting. The moment your seams differ from theirs, the twin stops being a twin.
Gate both ends. The carve has to come back zero-delta against the frozen baseline. The roll-up has to match the production render. One gate catches a bad cut; the other catches a bad landing.

The approach can be adapted to different stacks. The mapping and checks still have to fit the components, rendering, and interactions of the system being tested.
Where the AI actually sits
This is where I’ll be specific, because vague AI claims deserve the skepticism they get.
AI does the front half: the mechanical carve, the port, running the checks, generating synthetic data at realistic volume. That is a substantial part of the labor, and it makes this approach more practical for me.
The judgment stays mine. What’s worth stabilizing. What the delta means. Whether a failure is the gate being wrong or the work being wrong, which is a real question and the gate can’t answer it.
AI reduces the time I spend on those mechanical steps. That leaves more room to decide what is worth keeping and whether the evidence supports it.
Two questions to carry into the handoff
A spike in the real repo produces a real diff. The handoff needs to make it clear which behavior is proposed, which code is reusable, and what still needs engineering work. The prototype and the backlog should describe the same scope.
The other question is how big should a spike be? I keep it small enough to answer a specific question, and label the unfinished parts. Looking complete is not the same as being ready for production.
What is still being proved out
It’s being proved out. I’m not selling a framework.
The production-side check is human-supervised, with auth, tooling, and a real browser. It isn’t push-button. I’d love to claim otherwise and I’m not going to.
And the value isn’t that it guarantees parity. It’s that differences become measurable within the states we check, so the conversation has evidence beyond whose eye is better. A passing comparison does not establish usability, accessibility, or correctness in untested states. Those need their own checks.
