How to Vibecode

AGENTS · WORKFLOW · SHIPPING

This is for reasonably technical people who aren’t software engineers. “Vibecoding” here means you describe what you want in plain English, an AI agent writes the code, and you stay the person who decides whether it’s any good. It is not no code. You’ll read some. You just won’t type much of it.

The hard part isn’t getting something that kind of works. Getting to “kind of works” is an afternoon now, and it feels like magic. The hard part is week two: changing one thing without breaking the thing that already worked, knowing what state anything is in, getting back to safety when it all goes sideways, and putting it somewhere another human being can actually use it. None of that is a coding problem. It’s a workflow problem, and workflow is what this page is about.

The whole bill is one subscription, about $20 a month. GitHub is free, Cloudflare is free, the rest is free. By the end you’ll have something live on the internet at a URL you can text to someone. This is my setup, not the setup — I arrived at it by doing it wrong first, and it’s roughly the smallest amount of real development practice that pays for itself. Take the parts that help and throw out the rest.

The Shape of the Thing

The Loop

Before you install anything, know what loop you’re being taught. Everything in this guide is machinery wrapped around five steps:

  1. You describe what you want, in English.
  2. The agent edits the files.
  3. You run it and look at it with your own eyes.
  4. When it works, you save a checkpoint you can come back to.
  5. You push, and it’s live on the internet.

That’s it. Steps 1 and 2 are the part everyone talks about and the part that’s already solved. Steps 3, 4, and 5 are where projects die, and they’re where most of this page lives.

What you actually need

Four things, one of which costs money.

Thing What it’s for Cost
A terminal Where you talk to the agent. Already on your computer. Free
Claude Code The agent. Reads and edits the files in a folder, runs commands. ~$20/mo (Pro)
GitHub Save history for your project, and the trigger that deploys it. Free
Cloudflare Where the thing lives so other people can open it. Free

What I’m not going to explain

No computer science. No explanation of what a compiler is, what React is, or how HTTP works. You can be productive for a long time without any of it, and when you do need a piece, you can ask the agent for it right when it matters, which is when it’ll actually stick.

One rule I’m holding myself to on this page: every command shown here is one you type, and every file shown is one you own. I never show you code the agent writes. That code changes with every framework version, and copy-pasting it is how you end up with something you can’t maintain. The commands and the workflow files below have been stable for years.

Setup

Claude Code

This is the one thing you pay for. A Claude Pro subscription (about $20/month) includes Claude Code, which is the agent that runs in your terminal. Sign up at claude.com.

Here’s the single thing beginners misunderstand, so I’ll be blunt about it: Claude Code works on a folder. You cd into a directory, you type claude, and from that moment it can read and edit every file in there. It is not a chat window you copy answers out of. It is a coworker sitting at your computer with your project open. That’s why the rest of this page is about keeping that folder recoverable.

Install it

npm install -g @anthropic-ai/claude-code

cd ~/Projects/my-first-thing
claude

That needs Node.js installed first. If the install command has moved since I wrote this, the official docs win — and honestly, asking Claude in a browser “how do I install Claude Code on a Mac” is a perfectly good first move.

How to talk to it

You’ll get better results faster if you do these four things from day one:

  • Say what “done” looks like. Not “make the table better” but “the table should sort when I click a column header, and stay sorted when I add a row.” The agent is good at building to a spec and bad at guessing your taste.
  • One change at a time. A request with four unrelated parts gives you one big pile of edits you can’t evaluate. Four small requests give you four things you can check off.
  • When you’re unsure, ask before you edit. “Explain how this currently works and what you’d change, but don’t change anything yet” is a great habit. Read the answer. Then say go.
  • Tell it to actually run the thing. The agent can start your app, open it, and check the result. Ask it to. “It should work now” is not the same sentence as “I ran it and here’s what happened.”

GitHub

Git is two things at once, and it’s easier if you take them one at a time. It’s a save history for a folder — every version you ever checkpointed, kept forever, with the ability to go back. And it’s the trigger that puts your work on the internet — you’ll wire it up so that saving to GitHub updates your live site automatically.

Make a free account at github.com, then install GitHub’s command-line tool and log in. It’ll walk you through it with a series of questions; the defaults are fine.

brew install gh      # Mac, via Homebrew
gh auth login

We are not learning git yet. You need the account and you need to be logged in, and that’s all for now — the actual workflow comes after your first app is live, when it’ll mean something. If you learn branches and commits before you have anything worth protecting, none of it sticks.

Cloudflare

Make a free account at cloudflare.com. The free tier is genuinely generous — every project on this site runs on it and I’ve never paid for hosting.

You’ll meet two products. Pages hosts plain files: HTML, images, that sort of thing. Point it at a GitHub repository and it publishes what’s in there. Workers runs actual code on their servers, which is what you need once your app has to remember things between visits. Your first app uses Pages. Your third uses Workers.

I’m deliberately not giving you click-by-click instructions for the Cloudflare dashboard anywhere on this page. Those screens get redesigned every few months, and a stale set of directions is worse than none. I’ll tell you what you’re looking for and what it’s called, and you’ll find it — or you’ll paste what you see into Claude and ask which button to press.

Your First App

App 1 · A Page on the Internet

What you’re building

A single web page. A personal homepage, a list of links, a page about your dog. No framework, no build step, no database — one HTML file that a browser opens. Pick something you genuinely want to exist, because the point is that you’ll come back and change it. This site you’re reading right now is exactly this: a folder of HTML files with no build step, and it takes about ten seconds to go from edit to live.

How to do it

Make a folder, make a repository, and start the agent in it. gh repo create will ask you a few questions — make it private for now, you can always flip it later.

Then just ask. “Make me a single-page personal site with my name, a short bio, and links to my GitHub and email. Plain HTML and CSS, no frameworks. Put it in a folder called public.” Read what it produces — genuinely read it, HTML is about as approachable as code gets — and then look at it in a browser:

cd public
python3 -m http.server 8000
# then open http://localhost:8000

That command is a tiny web server built into your computer. It’s the same one I use to preview this site. Leave it running in one terminal window, edit in another, hit refresh.

When you like it, save it and send it to GitHub:

git add public/index.html
git commit -m "Add the first version of my personal site"
git push

Now go to Cloudflare and connect it. In the dashboard, find Workers & Pages and create a new Pages project connected to your GitHub repository. It’ll ask for a build command — leave it blank, you don’t have one — and a build output directory, which is public, the folder your HTML is in. A minute later you have a real URL.

What this teaches

  • A website is just files. The demystification alone is worth the hour.
  • The whole deploy loop: edit, commit, push, live. You will use this exact loop forever.
  • Local preview. You can always look at it before the world does.
  • Your first URL took an afternoon, not a semester.

Why This Is the Whole Game

Stop and appreciate what you have, because it’s more than it looks like. You can change something, see it locally, and have it live for anyone in the world a minute later. Every project in the rest of this guide is that same loop with more machinery in the middle. Not a different loop — the same one.

And this works flawlessly right up until the first time you ask for one more small thing and the agent breaks something that used to work. Which it will. That moment is what the next section exists for.

The Workflow

Branches, Commits, and Pull Requests

Three words that sound like jargon and are actually three very simple ideas.

A branch is a copy of your project you can throw away. You make one, you let the agent tear around in it, and if the result is garbage you delete the branch and it’s like it never happened. Your working version was never in danger. A commit is a save point with a note attached — a moment in time you can return to, and the unit of “this worked.” A pull request is a page on GitHub that shows you every single line that changed, before those changes become part of the real project. That review page is the whole point. It is the difference between an agent that helps you and an agent that quietly redecorates your house.

Here is the loop, and it’s the most important thing on this page:

git checkout -b feature/add-sorting    # a copy you can throw away

# ...work with the agent until it actually works...

git add public/index.html public/app.js   # only what you changed
git commit -m "Sort the table when a column header is clicked"
git push -u origin feature/add-sorting

gh pr create        # opens the review page
gh pr merge         # after you have read it

That’s six commands and it will carry you for years. The agent will happily run all of them for you — but do it by hand a few times first, because the muscle memory is what saves you at 11pm when something has gone wrong.

Branch names

Two prefixes cover everything: feature/short-description for new things and fix/short-description for repairs. Lowercase, dashes between words. This matters less than any other rule here; just be consistent enough that a list of branches tells you what you were doing.

Commit messages

A plain sentence, in the imperative, saying what changed: “Sort the table when a column header is clicked.” Not “updates” and not “fixed stuff.” The agent will write these for you and it’s good at it — your job is to read the message and check that it matches what you think happened. When it doesn’t, that’s useful information.

Pull requests

Write a paragraph, not just a title. What did you change, and why did it need changing? Have the agent draft it and then edit it. This feels like busywork on a project with one person, and then six weeks later you’re staring at a change you don’t remember making and the paragraph is the only thing that saves you. You’re writing to yourself.

Stage Only What You Changed

You’ll see git add -A and git add . everywhere on the internet. They mean “include everything.” Don’t use them. Name the files, like the example above does. It takes four extra seconds and it forces you to know what’s in your change.

Because here’s what actually happens: you ask for a button and the agent also reorganizes three other files it decided were untidy. If you typed git add -A, all of that is now in your commit and you don’t know it. If you named your files, you see the strays sitting there in git status. Files you didn’t ask for are the finding, not the nuisance. Go look at what it did.

What Not to Commit

A .gitignore file at the top of your project lists things git should pretend it can’t see. Everyone’s looks about the same:

node_modules/
dist/
.wrangler/
.dev.vars
*.local
.DS_Store

Those are build output, downloaded libraries, and machine junk — enormous, regenerable, and pointless to keep. The agent will write this file for you; you just need to know it exists and what it’s for.

The part worth doing yourself: if you’re going to test with real data, add it to .gitignore by name before the file exists. A folder called real_data/, a bank export, a spreadsheet with your actual finances in it. Do it in advance, because the moment you accidentally commit and push that file, it’s in the history and getting it out is genuinely difficult. Passwords and API keys get their own section further down.

Getting Back to Safety

This chapter is the reason for every chapter above it. It is 2am, the agent has been enthusiastic, and nothing works. Four commands:

git status                 # what changed?
git diff                   # show me the actual lines
git restore path/to/file   # undo my changes to this file
git checkout main          # abandon this branch entirely

git restore throws away edits to one file and puts it back the way it was at your last commit. git checkout main walks away from the whole branch and returns you to the last version you merged. Both of them only work because you committed when things were good. That’s the actual lesson: commit the moment something works, before you ask for the next thing. A save point costs you fifteen seconds and the absence of one costs you an evening.

The Gate

Before you open a pull request, one check has to pass. On App 1 the gate is “did I open it in a browser and look at it.” On a bigger project it becomes a command — on mine it’s npm run check, which type-checks the code and runs the tests, and I don’t open a PR until it’s green.

The principle matters more than the command. You need one yes-or-no answer that you trust, and it has to involve actually running the thing. A type-check passing means the code is shaped correctly, not that it does what you wanted. That distinction has bitten me more than once: everything green, everything broken. Open the app. Click the button. Look at the number.

Telling the Agent How You Work

CLAUDE.md

Every conversation with the agent starts from nothing. It doesn’t remember yesterday’s session, the decision you made last week, or the reason that one file is weird. A CLAUDE.md file at the top of your project is the fix — it gets read automatically at the start of every session. It’s memory that survives the conversation ending.

Mine are short. Three headings:

# CLAUDE.md

## What this is
A calculator that replaces my mortgage spreadsheet.

## Commands
npm run dev     # start it locally at localhost:5173
npm run check   # types + tests; must pass before a PR

## Things that aren't obvious
- The math lives in src/logic.ts and has no interface code in it.
  Tests check it against my original spreadsheet numbers. Keep it that way.
- Rates are stored as decimals (0.065), not percentages.

What belongs in it

  • What the project is, in one sentence.
  • The exact commands to run it and check it.
  • The handful of non-obvious decisions that would cost an hour to rediscover — and, ideally, why. “Don’t do X” gets ignored eventually. “Don’t do X because it broke Y” sticks.
  • How to verify a change actually worked. If checking your app means starting it and clicking three specific things, write those three things down and the agent will do them.

What doesn’t

  • Anything that changes every week — it’ll go stale and start actively misleading.
  • Anything the agent could learn by reading one file. It can read the files.
  • A list of everything you’ve ever done. That’s the next section.

A Note File for Future You

Separate from that, I keep a STATE.md in every project — a scratchpad of where things stand, rewritten whenever I stop working. Four things:

  • Status: am I actively on this, or is it parked?
  • What I just finished.
  • What’s next — concrete enough to start on without thinking.
  • What’s broken or half-done, so it doesn’t ambush me.

This is optional and it is very cheap. Twenty seconds when you stop; twenty minutes saved when you come back in three weeks with no idea what you were doing. Ask the agent to update it at the end of a session and you won’t even write it yourself.

A Real App

App 2 · Replace a Spreadsheet

What you’re building

A calculator that runs in a browser. There’s a build step now and the code is a real language, but still no server and no database — it saves in the browser.

Build a spreadsheet you already own and quietly resent:

  • A loan payoff or refinance comparison.
  • Unit conversion for a hobby — baking, brewing, woodworking, film stock.
  • Splitting costs on a group trip.
  • A training plan or a fertilizer schedule generator.

How to do it

Start a project from Cloudflare’s template and pick a React app with TypeScript when it asks:

npm create cloudflare@latest my-calculator

It’ll ask a handful of questions, and the exact wording changes over time, so I won’t transcribe them — you want a React app, TypeScript, and yes to deploying. Then hand the whole thing to the agent and describe your spreadsheet: the inputs, the outputs, the rules.

Here’s the one instruction that makes this project worth doing. Tell it to put the actual math in one plain file with no interface code in it — something like src/logic.ts — and to write tests for that file using real numbers out of your spreadsheet. You already know what the answers should be. That’s a genuinely valuable thing to have, and most people building software don’t.

Your spreadsheet is the test. Ten rows of known-correct inputs and outputs, turned into ten tests, and now every future change is checked against them automatically. That separation — math in one file, buttons in another — is the single most useful structural habit I have, because the math is the part that has to be right and the interface is the part you’ll change forty times.

What this teaches

  • A gate that means something. npm run check now runs your tests, and it can tell you that you broke the math.
  • Separating logic from interface, and why anyone bothers.
  • Scope creep. A calculator invites endless features and the agent will cheerfully build all of them. This is where you learn to say “good idea, not in this pull request.”

These are the five commands you’ll actually type from here on:

Command When What happens
npm run dev While working Runs the app on your machine, updating as you edit.
npm run check Before every PR Type-checks and runs the tests. The gate.
npm run db:migrate:local After a database change Updates the database on your machine (App 3).
npm run db:migrate:remote Before deploying that change Updates the real database (App 3).
Merge the pull request When it’s ready This is the deploy. Cloudflare rebuilds and ships it.

App 3 · Something That Remembers

What you’re building

Something with a database, so it still knows things when you come back tomorrow, on a different device. A home maintenance schedule. A log of things you’ve lent people. A reading list. Books, workouts, plant waterings, whatever. Single user — just you.

The parts

  • The page — what runs in the browser. Same as App 2.
  • The server — a small program on Cloudflare’s machines that the page talks to.
  • The database — where the data actually sits. Cloudflare’s is called D1 and the free tier is plenty.
  • Migrations — numbered files describing each change to the database’s shape, applied in order. Once real data exists, these are permanent history. Have the agent write a comment at the top of each one saying why.

The template sets all the plumbing up. There’s a config file with some settings in it that you will not need to understand on day one, and that’s genuinely fine.

Local vs. live

This is the thing that confuses everyone, so brace for it: you now have two databases. One on your laptop for development, one on Cloudflare’s servers for real. They are completely separate. That’s why there are two migrate commands in the table above — a schema change has to be applied to each.

So when you deploy for the first time and your live app is empty while your local one is full of test data: that’s not a bug. That’s the system working. Your test junk stayed on your laptop, which is exactly what you want.

Putting a lock on it

An app with your data in it shouldn’t be open to the world. Cloudflare Access solves this for free: it puts a login in front of your app and only lets your email address through. No password handling, no user accounts, no security code you have to get right.

The ordering is not obvious and getting it wrong costs you a confusing hour. Deploy first — that’s how you learn the address Cloudflare gave you. Then create an Access application for that address, with a policy allowing only your email. It gives you back two values, a team domain and an AUD tag; paste those into your project’s config and deploy again. Now the lock is on. Ask the agent to walk you through it — this is a great thing to have it explain step by step while you click.

Merging is deploying

Once the repository is connected to Cloudflare, merging a pull request into main builds and ships it automatically. There is no separate deploy step, and I love this — the review page is the last thing standing between an idea and production, which is a good place for your attention to be.

One caveat that’s invisible once you’re used to it: this only happens if you connected the repository to Cloudflare in the first place. If you merge and nothing changes on the live site, you probably haven’t — and you’ll waste an hour looking for a bug in your code that isn’t there.

Secrets

Sooner or later you’ll have an API key. Three kinds of values, three homes:

Kind of value Where it lives In git?
Settings that aren’t secret The project config file Yes
Real secrets, in production wrangler secret put NAME — typed in, stored by Cloudflare No
Real secrets, on your laptop A .dev.vars file, listed in .gitignore No

A nice habit: commit an example version of that local file with the names filled in and the values blank. Future you opens the project on a new machine and immediately knows which four secrets are needed.

And the part people get wrong, so I’ll say it loudly: if you commit and push a key, deleting the line does not help. It’s in the history. Bots scan public repositories for exactly this, within minutes. The only real fix is to go to whoever issued the key and revoke it, then generate a new one. Rotate the key. Don’t negotiate with yourself about it.


Then stop climbing for a while. Three apps in and you can build a genuinely useful amount of software. What I’d avoid next is anything holding other people’s logins, payments, or personal data. That’s a different sport with different consequences, and the gap between “works” and “safe to run” gets very wide very fast. Knowing where the ladder ends is part of using it well.

When It Goes Wrong

The Ways This Actually Fails

None of these are exotic. Every one of them has happened to me, most of them more than once.

  • The agent confidently breaks working code. The fix isn’t a cleverer prompt. The fix is that you were on a branch and you committed the version that worked. Commit when it works, before you ask for the next thing.
  • You never actually ran it. The agent said “done,” the type-check was green, and nobody opened the app. Open the app.
  • The conversation got too long. Long sessions drift — the agent loses track of a decision from an hour ago and quietly re-litigates it. Keep a session to one change, put durable facts in CLAUDE.md rather than in the chat, and start fresh after each merge.
  • You asked for a button and got a refactor. Read the diff before you commit; stage only the files you meant to touch. On a branch that’s a two-minute cleanup. On main it’s your evening.
  • A secret went into git. Pasted into a file, committed, pushed. Prevention is .gitignore and wrangler secret put. Cure is rotating the key — there isn’t another one.
  • It fixed the symptom. An agent will happily wrap a check around an error while the actual cause sits upstream, untouched, waiting. Make it reproduce the failure and tell you what’s causing it before it changes anything.
  • You came back after three weeks with no idea where you were. That’s what the note file is for.
  • You built for users who don’t exist. Ship for one user — you — and add the rest when somebody actually asks.

What This Doesn’t Get You

An honest list, because the enthusiasm around this stuff tends to skip it. Free tiers have real limits, and the way you hit one is that your app starts failing in a way that looks exactly like a bug in your code — so when something inexplicable starts happening at scale, check the platform’s limits before you go hunting through your own work.

An agent will build what you describe, which means you still have to know what you want, and being clear about that turns out to be most of the job. And whatever ships has your name on it. “The AI wrote it” is not a thing you get to say about your own software — not to your users and not to yourself. That’s the deal, and it’s a fair one.

If You Want to Build an iPhone App

The Same Loop, Different Machinery

I build iOS apps too, and the surprising thing is how little the workflow changes. Branches, commits, pull requests, CLAUDE.md, commit-when-it-works, read-the-diff — all identical. What swaps out is the machinery around them:

  • Xcode and the simulator replace the dev server. Instead of refreshing a browser tab you press Run and a fake iPhone appears on your screen.
  • A config file replaces .dev.vars for secrets — different name, same idea, same .gitignore discipline, same “commit the example, not the real one.”
  • Merging is no longer deploying. Releases go through TestFlight and then a human review queue at Apple that takes a day or two. Shipping becomes an event you plan rather than a reflex, which changes the rhythm of the work more than anything else on this list.
  • The App Store demands a support URL and a privacy policy URL before it’ll take your app — which is an excellent reason to already own App 1. Two more HTML files on the site you built in an afternoon, and you’ve satisfied Apple.

One honest note: this is where the “free” promise breaks. Building and running on the simulator costs nothing, but putting an app on the App Store requires the Apple Developer Program at $99 a year. Worth knowing before you get attached.

Start Here

Your First Afternoon

Concretely, the next five things:

  1. Subscribe to Claude Pro and install Claude Code.
  2. Make a GitHub account and run gh auth login.
  3. Make a free Cloudflare account. Don’t click anything yet.
  4. Build App 1 — one page, about something you care about — and get it live.
  5. Then come back and read The Workflow again. It’ll mean something different once you have a thing to lose.

That’s the whole guide. It’s the setup I actually use, arrived at by doing it wrong first — not a best practice handed down from anywhere. If some part of it feels like ceremony that isn’t earning its keep on your project, drop it. The only two I’d genuinely fight you over are commit when it works and read the diff before you merge. Everything else on this page is in service of those two.