ideastack·8 min read·
Claude Code plan mode for UK indie hackers: the three-screen ritual that stops the one-shot disaster
The fastest way to brick a weekend project is to one-shot a refactor. Plan mode is Shift+Tab+Tab and a fundamentally different agent posture - the agent looks, drafts a plan, and only edits once you've agreed. The three-screen ritual that stops the one-shot disaster on Stripe Checkout, live Supabase migrations, and billing webhook rewrites.

The fastest way to brick a weekend project is to one-shot a refactor. You're tired, it's 22:00 on a Sunday, you type "rewrite the Stripe webhook to handle GoCardless too" and hit return. Claude Code makes 14 edits across 9 files. The build goes red. You can't read what changed because you scrolled past most of it. The migration ran on your live Supabase. Monday morning you have a broken billing flow and no clean rollback point.
Claude Code's plan mode is the fix. It is two keystrokes — Shift+Tab, Shift+Tab — and it changes the agent's whole posture: from "shipper" to "drafter". The agent writes a plan instead of editing files. You read the plan. You correct it. Then you exit plan mode and let the agent execute the corrected plan. Three screens, zero one-shot disasters.
This post is the UK indie hacker's plan-mode primer. The three-screen ritual. What a good plan looks like vs a bad one. Three concrete UK scenarios where plan mode saves a weekend. And the one moment when you should skip it.
What plan mode actually is (45 seconds)
By default, Claude Code is in "edit mode". Press Shift+Tab once and it switches to "auto-accept edits". Press it twice and you enter plan mode.
In plan mode the agent keeps Read, Glob, Grep, and Bash but physically loses Edit, Write, and any mutating tool. It looks; it does not change. When it has enough information, it emits a structured plan: ordered steps, file paths, test commands.
You read the plan. You can ask follow-up questions inside plan mode (still no edits). You accept it (which exits plan mode and starts execution) or ask for revisions. Two keystrokes; a fundamentally different agent posture.
The three-screen ritual
The discipline that pays for plan mode is simple. Three screens, in order, every time you start a non-trivial change.
Screen 1: enter plan mode and state the goal
Shift+Tab+Tab to enter plan mode. State the goal precisely. The trap is stating the goal as "make X work"; the unlock is stating it with the constraints baked in.
Bad:
Add Stripe Checkout to the pricing page.
Good:
Add Stripe Checkout to /app/pricing/page.tsx. GBP 9.99/month and
GBP 79/year tiers. Stripe Checkout in embedded mode (not redirect).
On success, write to public.subscriptions with status='active'.
Use server actions, not API routes. Do not touch the Resend webhook
or the Supabase RLS policies for now.
The second prompt sets up the agent to write a plan you can actually read. The first sets it up to write a plan that's mostly "I'll figure it out".
Screen 2: scan the plan, push back
The agent writes a plan. You read it top to bottom. Three questions to ask:
- Does each step include a file path or a command? If a step says "set up Stripe Checkout" without naming a file, the agent doesn't know what it's doing yet. Push back: "which file gets the checkout component?"
- Are the test commands in the plan? A good plan includes "run
pnpm test app/pricingafter step 3". A bad plan ends with "and that should work". Push back. - Is anything in the plan you didn't ask for? Plans that say "I'll also refactor the auth helper while I'm in there" are a red flag. The whole point of plan mode is scope control. Push back: "skip the auth refactor; keep this change tight."
After the second revision the plan should fit on one screen. If it's two screens, the change is too big — break it into two plans and do them as two separate exits-and-executes.
Screen 3: exit and execute
When the plan is correct, accept it. Claude Code exits plan mode and starts executing the plan in order. You can watch each step, but you don't have to babysit — the plan is already agreed, the agent just runs it.
This is where the safety comes from. The agent isn't deciding what to do as it goes (the one-shot disaster mode); it is executing a plan you both already read and agreed on. If a step blows up, you stop, fix it, and either resume or re-plan. Either way, you're never more than one step away from a clean state.
What a good plan looks like (vs a bad one)
The agent's first draft is rarely a good plan. Here's the same Stripe Checkout job in both shapes so you can spot the difference.
Bad plan (one-paragraph waffle)
I'll add Stripe Checkout to the pricing page. First I'll update
the pricing page component to include a checkout button, then
I'll set up the Stripe SDK and wire up the session creation. I'll
also add a success page and a webhook handler. This should work
for both GBP tiers.
This is what a fresh, prompted-too-vaguely agent writes. There are no files, no commands, no test steps, no error cases. If you accept this plan, you are essentially saying "do whatever, I'll find out in the diff". One-shot disaster waiting to happen.
Good plan (numbered, file-specific, testable)
Plan: Add Stripe Checkout (embedded) for GBP 9.99/mo and GBP 79/yr.
1. Create app/lib/stripe.ts. Export `stripe` client wired to
STRIPE_SECRET_KEY. Export prices object:
{ monthly: 'price_xxx', yearly: 'price_yyy' }.
2. Create app/pricing/checkout-action.ts (server action). Takes
tier ('monthly'|'yearly'), returns clientSecret from
stripe.checkout.sessions.create({ ui_mode: 'embedded',
mode: 'subscription', line_items: [{ price, quantity: 1 }] }).
3. Edit app/pricing/page.tsx. Add two CTA buttons. On click, call
checkout-action, then mount @stripe/react-stripe-js
EmbeddedCheckout with clientSecret. Use 'use client' for the
button + checkout sub-component only; keep the rest as server.
4. Create app/api/stripe/webhook/route.ts. Verify signature with
STRIPE_WEBHOOK_SECRET. On checkout.session.completed, write to
public.subscriptions (user_id from session.metadata.user_id,
status='active', stripe_subscription_id, tier).
5. Run `pnpm test app/pricing` and `pnpm test app/api/stripe`.
Both should pass.
6. Manual smoke test: hit /pricing, click GBP 9.99/mo, complete
with test card 4242 4242 4242 4242, check Supabase
public.subscriptions for new row.
Files to be changed: 4 new, 1 edited.
No changes to: existing auth, existing RLS, Resend integration.
That's a plan you can read and trust. Every step has a file path, every step has a test step, the scope is explicit and bounded.
Three UK scenarios where plan mode saves a weekend
Scenario 1: adding Stripe Checkout to a Next.js 16 micro-SaaS
The one above. The risks of one-shotting this on a Sunday evening: wiring the API key into client code by accident; building a redirect-mode checkout when you wanted embedded; forgetting the webhook signature verification (and then forgetting to add it later); inserting the wrong currency code at the price level. Plan mode catches all of these because each becomes a step you read before it runs.
Scenario 2: migrating a live Supabase table without losing rows
You realise the subscriptions table needs a cancelled_at column. The agent can write the migration in 30 seconds. It can also accidentally write a migration that drops a column or rebuilds the table with a different default. On a live UK micro-SaaS with paying users, that's a recovery operation.
Plan mode forces the migration into a readable shape:
Plan: Add cancelled_at to public.subscriptions.
1. Create supabase/migrations/20260513_add_cancelled_at.sql with:
ALTER TABLE public.subscriptions
ADD COLUMN cancelled_at timestamptz NULL;
2. Run `supabase db diff --linked` to verify the migration only
adds the column (no other changes).
3. Apply with `supabase db push --linked`.
4. Verify with:
SELECT column_name FROM information_schema.columns
WHERE table_name='subscriptions';
Confirm cancelled_at present.
No data changes. No other schema changes.
Three steps, one column, no surprises. If supabase db diff shows anything other than the column add, you abort before pushing.
Scenario 3: rewriting a billing webhook handler
The classic late-Sunday refactor. A 200-line webhook handler that accreted three vendors over six months. Edit mode rewrites it in one go; you read the diff at midnight hoping to spot the regression. Plan mode is the right tool:
Plan: Refactor app/api/stripe/webhook/route.ts.
1. Identify the four event handlers in the existing route:
checkout.session.completed, invoice.paid,
customer.subscription.updated, customer.subscription.deleted.
2. Extract each into app/api/stripe/handlers/<event>.ts, exporting
`handle(event: Stripe.Event)` returning Response.
3. Rewrite route.ts as a dispatcher: verify signature, switch on
event.type, call the right handler, return its Response.
4. Add a .test.ts next to each handler. Happy path + one failure
case per event.
5. Run `pnpm test app/api/stripe`. Confirm green.
6. Smoke test: `stripe trigger checkout.session.completed` and
verify the local server returns 200 and writes the expected row.
Total: 4 new files, 1 file rewritten. Structural change only - no
handler-body logic touched.
A refactor you can ship at 22:00 on Sunday without sweating about Monday's email from your first GBP 9.99 customer.
The one moment to skip plan mode
Plan mode is overkill for changes you've made 50 times before. Renaming a variable across three files. Adding a missing await. Fixing a typo in a CTA button. The setup cost (entering plan, reading the plan, exiting) is longer than the change itself.
Rule of thumb: if the change is one file and one minute, skip plan mode. If it's two files or two minutes or you cannot fully describe the change in one sentence, use plan mode.
The mid-case is two minutes of typing in plan mode for what would be 30 seconds in edit mode — but plan mode caught the thing you would have missed. After a few of those, you stop minding the 90 seconds of overhead. It is, by a wide margin, the cheapest insurance Claude Code offers.
The plan-mode habit, in one line
The habit that compounds: never type a destructive prompt outside plan mode. Anything that edits production schema, rewrites a billing handler, or touches Stripe/Supabase config goes through plan-mode first. Everything else is edit mode. After three or four weekend builds, the habit becomes automatic — your fingers reach for Shift+Tab+Tab before your brain reaches for "make it work".
Want a data-backed UK business idea every week? Free reports drop every Thursday — keyword volumes, SERP analysis, builder prompts. Browse the latest free report on IdeaStack.
Frequently asked
How do I exit plan mode without accepting the plan?
`Esc` cancels and keeps you in plan mode. Press `Shift+Tab` to cycle back to edit mode without accepting. If you accept a plan by mistake, `Ctrl+C` during execution stops the agent mid-step. Files already edited stay edited — `git checkout .` to rewind.
Does plan mode use more tokens than edit mode?
Slightly more on the planning turn (the agent does more reading and writes the plan), slightly fewer on the execution turn (the agent doesn't re-derive the plan as it goes). Net per session: about the same, sometimes 5-10% more. For a UK indie hacker on Claude Pro, this is comfortably inside the quota. The value is in the disasters you don't have to recover from, not the tokens you save.
Can I save a plan and execute it tomorrow?
Not natively, but you can copy the plan into a markdown file in your repo (call it `plans/2026-05-13-stripe-checkout.md`) and paste it back into Claude Code the next day. The agent reads the plan and executes it the same way as if you'd just generated it. This is also a great pattern for "I planned it Friday evening, I'll execute it Saturday morning when fresh".
What if the plan reveals I don't actually understand the change?
This is the best possible plan-mode outcome. You hit Esc, close Claude Code, read the Stripe or Supabase docs for 15 minutes, come back, write a clearer prompt. Plan mode that surfaces "I don't know enough to do this yet" has paid for itself five times over by stopping you from one-shotting something you didn't understand.
Does plan mode work in Cursor or OpenCode?
Cursor has an "ask before edit" mode but it's gated per-edit, not plan-then-execute. OpenCode has a `plan` slash command that's closer but less mature in 2026. Plan mode is one of the two or three features that makes Claude Code feel structurally safer than the alternatives for production-shaped weekend work.
Filed under





