Vibe coding version one is basically solved. What's your month-two experience?
The tools keep getting better at the first week. Describe an app, get an app. Impressive and the demos aren't lying.
What I keep hearing about (and lived myself) is month two. You ask for one change and five files move. Styling drifts. The AI forgets decisions from last week because the only place your app's structure exists is the chat history and the chat history runs out. Every builder community has the same complaints in almost the same words.
So, honest questions for people actually shipping with these tools:
What's the longest you've kept a vibe-coded app alive and evolving and what finally made it painful?
What's your workaround: restore points, rebuilding cleanly from a mockup, exporting to Cursor, something else?
Has anyone gotten one through a real reorganisation, new roles, changed process without a rebuild?
Full disclosure: I'm building in this space but this thread isn't a pitch, the workarounds people have actually found are more interesting to me than my own answer.
Replies
The hardest part seems less about generating code and more about keeping the project decisions consistent when the app starts growing.
@aaron_aberasturia45 Yeah, generation is a solved problem but consistency is an unsolved one and it gets worse non-linearly as the app grows. The reason is mechanical since every decision you made lives nowhere. Each new change quietly re-litigates all of them, because the AI re-derives the app from scratch every time and the decisions were never written anywhere it can read.
Small apps hide this - few decisions, all recent, all still in the context window. Growth is what breaks it: more decisions, older decisions, and one day the change that contradicts decision #14 from six weeks ago ships without anyone noticing. That's the day people start being afraid of their own app.
The fix, whatever tool you use: decisions need a home that outlives the conversation and ideally one the machine is forced to respect, not just invited to read.
I’ve had the same issue where the first version feels easy, then small changes start touching unexpected parts of the project.
@brody_vincent Yes and the counterintuitive part is that it's not the AI being careless. It literally can't prove a small edit is safe so regenerating wide is the rational move from where it sits. Thirty changes later, the graveyard.
What helps regardless of tool: one small change per request, name the exact file or component, snapshot before every change so a bad one is a revert and do your heavy iteration on a disposable copy then apply the final version once.
Wrote up the full mechanism and the workarounds here if useful: chromoly.io/why-ai-changes-unrelated-code the first half is tool-agnostic advice, no signup anywhere.
@david_brandt3 the chat history point is the real issue. Once your app's structure only exists in a conversation that eventually runs out, there is no durable record of the decisions that got you there. Calling it forgetting undersells it, the AI never had anywhere to keep that information to begin with. The workaround that tends to hold up is treating a written spec or architecture doc as the source of truth (we use Notion for that) and feeding the agent from that. Rebuilding clean from a mockup works too, it just costs more time than people admit upfront.
@alex_gidirim The AI never had anywhere to keep that information to begin with - that's a sharper way to put it than forgetting and I might steal it. Exactly, it's not memory loss, it's that no memory was ever designed.
The Notion-spec workaround is the correct instinct. You've hand-built the missing artifact. Its limit shows up around week six when the doc is advisory, so nothing stops the code and the spec from quietly disagreeing. You catch drift by reading, which works right up until you're busy.
That gap is basically why we built what we're building: the spec as the thing the system is actually compiled from, so code and spec can't disagree - disagreement isn't caught, it's impossible. Same idea as your Notion doc, just enforced by the machine instead of discipline.
And agreed on rebuild-from-mockup. It works and everyone underestimates the cost of the one clean pass.
Fourteen months on the same codebase, with the same agent, and what finally worked was not a huge spec. It was a short list of rules the agent has to read every session, with the important ones backed by tests.
The doc is short on purpose: one rule per line, no long explanations, plus a table showing which file to read before changing each part of the app. The details stay in those files, so the main doc stays short enough that the agent actually reads it.
Every time things went off track, it was because some rule existed only in my head. So now the rule is simple: if the code needs a new rule, I add that rule in the same change. Not later.
I would argue a bit on the idea that "code and spec can never disagree." The biggest problems I had were not really code problems. For example: text still promising a feature we removed, an old pricing claim in the FAQ, or the wrong feature being marked as paid. The compiler will not catch that.
A simple test can. It can search the app for old claims and fail the build if it finds them. Pretty dumb, but it has caught more issues than code review.
What it still does not solve is design drift and taste. A test cannot tell you "this looks weird." I still need to open the page and check it myself
And the rules doc can also become messy if the agent is allowed to change it freely. I only add to mine manually, one line at a time.
@siarheihamanovich Fourteen months of receipts beats theory and this is the right place to push. Let me split it, because the compiler covers more of your examples than you'd expect and less than everything.
Your examples - text promising a removed feature, the wrong thing marked as paid are mostly references, and references are exactly what a compiled system tracks. In our setup the app's UI isn't hand-maintained text, it's generated from the spec: remove a workflow from the spec and the screens referencing it regenerate without it. There's no orphaned button or stale label, because the label was never written by hand in the first place. And the dependency map flags anything still pointing at a removed thing before the change applies. So the app still mentions a feature we deleted is structurally hard to produce here.
What the compiler genuinely can't catch: A welcome message mentioning a retired workflow, an email template with an old price - that's meaning, not references, and your dumb grep test is the honest fix there. I'm stealing it.
Full disclosure: our own marketing site isn't built on Chromoly, so it gets exactly the manual discipline you describe and yes, a stale claim survived months there until I caught it by reading. The gap between compiled surfaces and hand-written ones is real, and it's the strongest argument for compiling more of them.