← Blog

Studio of One ¡ Part 2

Vibe Coding Gets You a Demo. This Gets You to Production

Bolt, Lovable, and vibe coding get you a demo fast. Shipping a real system takes agentic practices: specs, checks, guards, and review. Here are the ones I use.

Josh McWilliam

7 min read

  • vibe-coding
  • production
  • claude-code
  • agentic-systems
  • platform

I vibe code.

I want to say that up front, because this post is going to sound like an argument against it, and it isn’t. Andrej Karpathy named the practice in a post on X in February 2025: you “fully give in to the vibes, embrace exponentials, and forget that the code even exists.” By the end of the year Collins had made it their word of the year. It’s the fastest way I know to find out whether an idea is worth building.

It is also, in my experience, the fastest way to end up with a demo you can’t ship. The difference between the two outcomes isn’t the tool. It’s what you do around it.

Fair credit first

The prompt-to-app builders are genuinely good at what they’re for. Describe an app and you get screens, forms, a data model, basic sign-in, and a deploy button, usually on top of a hosted backend. What used to take a weekend takes an afternoon.

For a demo, that’s not the first 20% of the work. That’s the whole thing. If the goal is to show someone what you mean, or to find out whether anyone cares, use the fastest tool and don’t apologize for it.

The trouble starts when the demo works and you decide to keep it.

Where the demo stops

Here’s the line I keep hitting, in roughly the order I hit it. None of this is a knock on the tools. It’s a description of where “an app” turns into “a system.”

Authorization beyond login. Sign-in is easy. Roles, organizations, “this user can see that record but not edit it,” and multi-tenant data are where the generated code starts guessing, and a wrong guess here is a security hole.

Background work. Anything scheduled, queued, retried, or long-running. Demos are request-and-response. Businesses are mostly things that happen when nobody’s looking.

Integrations that fail. The first call to a payment provider or an email API works. The tenth, when the provider times out and you need idempotency so a customer isn’t charged twice, is a different problem.

Data that changes shape. The moment the model needs to change under real records, you need migrations, and a builder that regenerates the schema from a prompt is a builder that will lose your data.

Observability. When it breaks, and it will, can you tell what happened? Demos don’t need logs. Anything with a customer does.

The second developer. For me that’s future me, six months on, opening a codebase I didn’t write. Generated code with no structure and no tests is unreadable by anyone, including the person who prompted it.

Tests. Not because tests are virtuous. Because tests are how an agent knows it’s done, which is the whole subject of the second half of this post.

The pattern is that vibe coding is superb at the part of the system you can see and weak at the part you can’t. Unfortunately, the part you can’t see is most of a business.

Speed isn’t automatic

I’d be cheating if I told you that switching to “agentic” tools fixes this by itself. The evidence says it doesn’t.

In July 2025, METR ran a randomized controlled trial with sixteen experienced open-source developers working in their own large repositories. With AI tools allowed, they took 19% longer to finish tasks. They had expected to be 24% faster. Afterwards, they still believed they’d been about 20% faster.

The 2024 DORA report found something similar at the organizational level: AI adoption improved individual productivity and satisfaction while hurting software delivery throughput and stability. Its advice was the least glamorous kind: small batches, robust testing.

I believe both of those findings, and I also ship more alone than I used to ship with a team. The reconciliation is that the gain doesn’t come from the tool. It comes from practice around the tool that makes checking faster than doing. Without that practice, agents just generate wrong code faster, and you become the verification loop.

The practices, with receipts

Everything below is something I actually do, with the artifact from the studio that proves it. I’ve linked to what’s public.

1. Write the spec before the build

For a small change, I just do it. For anything that touches more than one file or one decision, I write down what’s changing, why, and, most importantly, what I’ve decided not to claim or build. When this site was repositioned in early September, that was a spec with a decision table: what’s live, what’s coming soon, what’s out of scope.

Anthropic’s own guidance for Claude Code says the same thing in fewer words: explore first, then plan, then code. Letting the agent jump straight to building “can produce code that solves the wrong problem.” It can. I’ve watched it.

2. Work in phases with a check between each

The studio’s method has five phases: Frame, Architect, Build, Evaluate, Release. That’s the workflow the Faber tooling encodes, and it’s how every change here ships. The important word is “between.” The agent that builds a thing is not the one that decides it’s done.

3. Give the agent a check it can run

This is the single practice I’d keep if I could only keep one. From the same Claude Code guidance: “Give Claude a check it can run: tests, a build, a screenshot to compare. It’s the difference between a session you watch and one you walk away from.”

For this site, the check is a type check, a full build, a content guard, and a link checker, all behind one command. The agent runs it, reads the failure, fixes the failure, runs it again. I only look when it passes. The guidance’s other line is the one I’d tattoo somewhere: “If you can’t verify it, don’t ship it.”

4. Turn your past mistakes into build failures

The content guard deserves its own paragraph. It’s a short script that scans every generated page for strings that must never appear: a name I’ve decided not to use, a claim I’ve decided not to make, a link to a page that no longer exists, a placeholder that was supposed to be filled in. If it finds one, the build fails and nothing deploys.

Every rule in that list is a mistake that already happened once. That’s the point. An agent will make the same plausible mistake again, and so will I. The guard doesn’t care which of us made it. It’s the cheapest, most reliable engineer in the studio.

5. Branches, pull requests, and a human on every diff

Nothing ships from a working directory. Every change is a branch and a pull request, and I read every diff before it merges. That review is the biggest recurring cost in the studio and I’ve stopped trying to eliminate it. It’s the cost of shipping reviewed code, which is the only kind worth shipping.

6. Let the documentation follow the code

Agents work from written context. The conventions here live in one place and are distributed to every repo that needs them by Codex, so the agent building in this repo knows the rules without my repeating them, and when a rule changes, every repo gets the change. The Claude Code guidance calls the per-project version of this a CLAUDE.md and says to treat it like code: prune it, test it, and notice when the agent stops following it. That’s been my experience exactly.

7. Keep everything in formats you could leave with

Markdown, YAML, JSON, and a site that’s a folder of files. If I stopped using every tool in the studio tomorrow, I’d still have all the work. That’s not paranoia. It’s what lets me change tools without changing the business, and it’s what makes the work legible to the next agent, or the next me.

The rule underneath

If there’s one idea in all of that, it’s this: move the discipline out of your head and into the system.

Vibe coding fails in production not because the code is generated but because the discipline is optional. Every practice above makes something that used to depend on remembering into something that runs whether you remember or not. The spec is written down. The check runs by itself. The guard fails the build. The review is a step you can’t skip.

That’s what “agentic” means to me in practice. Not an agent that does everything. A system in which the agent does the doing, the checks do the checking, and the human does the deciding.

For the teenager, and for the founder

If you’re a teenager, or the parent of one: this is why Make First teaches building with AI tools rather than coding, and why it still has pass/fail gates at every stage. The gate is the discipline. A first build that a stranger can use, evidenced by a URL, is a check the student can run. That’s the same idea as everything above, scaled to a first business.

If you’re a founder building alone: the stack I do this with is open source, Apache-2.0, on the Platform page, and the tools I reach for are in the Stockyard, with their sources labeled and no affiliate links. Vibe code the demo. Then do the boring part. The boring part is the business.


This is the second post in the Studio of One series. Previous: How I Run a Dozen Ventures Alone. The argument about owning your stack is in Platform Limitations Are Your Prison.

The Stack

Build on the stack the studio builds with.

Open-source, Apache-2.0 tools for building agentic systems without vendor lock-in. The same stack behind every venture on this site.