Vibe Coded Today

Prompt snippets · 26 pages

Writing & changing code

Adding features, refactoring, and stopping the model rewriting what already works.

Make it smaller

Refactor without silently changing behaviour or breaking your other files.

make-it-smaller.txt
Refactor this file. Constraints:
- Behaviour must not change. If you think a behaviour is a bug, flag it,
  don't silently fix it.
- No new dependencies.
- Keep the same public function/export names so my other files still work.
- Show me the full new file, then a short list of what you changed and why.

<paste file>

Review my vibe code

Run this over every file before anything goes public.

review-my-vibe-code.txt
Review this code the way a sceptical senior dev would. Look for:
1. Things that will break with real user input (empty, huge, weird characters).
2. Anything secret that shouldn't be in the file (API keys, tokens, passwords).
3. Anything that talks to a database or the network without error handling.
4. Copy-pasted blocks that should be one function.

For each finding: the line, why it matters, and the smallest fix.
Rank by "would actually bite me" — skip style nitpicks.

<paste file>

Point 2 is the one that matters most. An API key in a file you upload is a public API key, and bots find them within minutes.

Stop the rewrite

For when you asked for one change and got a whole new file.

stop-the-rewrite.txt
You rewrote more than I asked. Undo that.

Go back to my original file and change ONLY: <the one thing>
Everything else stays byte-for-byte identical.
Show me a diff, not the whole file.

Write the tests first

Make the model prove what "working" means before it builds it.

write-the-tests-first.txt
Feature: <describe it>

Before writing the implementation, write the tests. I want:
- The happy path.
- Two realistic ways a user breaks it.
- One edge case I probably haven't thought of.

Use <testing framework, or "the simplest thing that runs with no setup">.
Show me the tests and stop. I will read them and tell you if they
describe the thing I actually asked for.

Tests written before the code are a specification you can run. Tests written after it are a description of whatever got built.

Add a feature without breaking the last one

The prompt that keeps working code working.

add-a-feature-safely.txt
Working code is attached. It currently does <what works today> and I
need that to keep working exactly as it does now.

Add: <the new feature>

Rules:
- Show me a diff or the changed sections only, not the whole file.
- Do not rename or restructure anything you were not asked to change.
- If the new feature genuinely requires changing existing behaviour,
  stop and tell me what and why before you write it.

Most "the AI broke my app" moments are a model helpfully modernising code you never asked it to touch. Say the working parts are off limits, every time.

Refactor exactly one thing

Scope the blast radius to a single function.

refactor-one-function.txt
Here is one function: <paste>

It works. I don't want new behaviour — I want it easier to read.

- Same inputs, same outputs, same side effects.
- Tell me first, in two lines, what makes it hard to read.
- Then the rewrite.
- Then list anything the rewrite changed that I should test.

Do not touch anything outside this function.

"Refactor this" with no boundary is an invitation to rewrite your project. One function, stated behaviour, explicit limits.

Fix the names

Cheapest readability win there is.

name-things-well.txt
Here is my code: <paste>

Don't change any logic. Just tell me which names are wrong, and what
they should be. For each one, one line on why.

Look for: names that lie about what the thing holds, names that need a
comment to be understood, single letters outside short loops, and
functions whose name says less than they do.

If a function needs a comment to explain what it returns, the name is doing the wrong job. Renaming is the safest change you can make.

This file is too big

Split it without breaking it.

shrink-my-file.txt
This file has grown to <n> lines and I've lost the thread: <paste>

Propose a split. For each new file: the name, what moves into it, and
what it exports. Show me the plan as a list — no code yet.

Prefer the fewest files that fix the problem. If you think it should
stay as one file, say that instead and tell me why.

Ask whether it should be split at all. Models will happily produce eight files where two would do, and a maze of tiny files is harder to hold in your head than one long one.

Move it to a different stack

In slices, with something working at every step.

migrate-framework.txt
I have <current stack> and I want to get to <target>. Here's the code:
<paste or describe>

Do NOT rewrite it all at once. Give me a migration plan where the app
works after every step:
- What moves first, and why that piece.
- How the old and new parts talk to each other during the transition.
- The point of no return, and what I should verify before it.
- What I could keep on the old stack forever without shame.

Then we do step one, and only step one.

A big-bang rewrite is a project with no working version in the middle and no honest way to measure progress. Slices give you both.

Turn the types up slowly

Strict mode all at once produces 400 errors and a closed editor.

typescript-strictify.txt
This project has types switched on loosely. I want strict, eventually.

- Turn on one compiler flag at a time. Tell me the order, easiest first.
- For the flag we're doing now, show me the errors it will produce and
  fix them in batches by kind, not file by file.
- Where a real fix needs restructuring, say so and leave a marked
  escape hatch rather than pretending with `any`.

Do not add `any` to make an error go away without telling me.

A silenced type error is worse than an untyped file: it looks checked. Flag every escape hatch so you can find them again.

Find the code nobody runs

Generated projects accumulate this fast.

dead-code.txt
Here's my project: <paste files or the file list plus key files>

Find what isn't used:
- Functions never called.
- Imports never referenced.
- Variables assigned and never read.
- Files nothing imports.
- Config options nothing reads.
- Entire features I appear to have abandoned halfway.

For each: how confident are you it's genuinely unused, given you can
only see what I've pasted? Flag anything that might be called
dynamically or from a file you haven't seen.

Rank by how safe it is to delete.

Delete in a separate commit from anything else. Then reverting a wrong deletion is one command rather than an archaeology exercise.

Find the same thing written three times

The characteristic shape of vibe-coded code.

find-duplicates.txt
Here's my code: <paste>

Find near-duplicates — blocks doing the same job with small
variations. This happens when I ask for similar things in separate
conversations.

For each cluster:
- What they have in common and how they differ.
- Whether they should genuinely be one function, or whether the
  differences mean they should stay separate.
- If they should merge, show me the merged version and every call site
  that changes.

Be honest when the answer is "leave them alone". Two similar functions
are often better than one with four flags.

The premature-abstraction failure is real. A shared function with a boolean parameter that changes half its behaviour is worse than the duplication it replaced.

Review it like a stranger would

A structured pass over code you're too close to.

stranger-review.txt
Review this as if you'd just joined the project and have to maintain
it: <paste>

Answer in this order:
1. What does this do? If you can't tell in 30 seconds, say what's
   in the way.
2. What would surprise you here — anything doing something other than
   what its name suggests?
3. What breaks with unexpected input: empty, null, enormous, the
   wrong type, hostile?
4. What's not handled — errors swallowed, cases ignored?
5. What would you have to ask the author about?

Then: the three changes with the best ratio of improvement to risk.

Question 5 is the useful one. Every item in that answer is something that only exists in your head, and it's the list of comments actually worth writing.

Add types to untyped code

Incrementally, without a wall of errors.

add-types.txt
This code has no types: <paste>

Add them incrementally:
- Start with the boundaries — function inputs and outputs, and the
  shape of anything coming from an API or a database.
- Types that describe reality, including nullable fields and the
  shape of an error response. Don't pretend everything is always
  present.
- Where the real type is genuinely dynamic, say so explicitly rather
  than using a permissive escape hatch quietly.

List every place you had to widen a type or use an escape hatch, and
why. Those are the places my code is doing something I should look at.

The escape-hatch list is the valuable output. Each one is either a genuine dynamic case or a piece of code whose behaviour you can't actually describe.

Make this simpler

Not shorter. Simpler.

simplify.txt
This works but it's hard to follow: <paste>

Simplify it. Behaviour must be identical.

Look for:
- Nesting that could be flattened with early returns.
- Conditions that could be named instead of inlined.
- Steps that happen in a confusing order.
- Flags and parameters that change what the function fundamentally is
  — those usually want to be two functions.

Tell me first, in two lines, what specifically makes it hard to
follow. Then the rewrite. Don't make it shorter at the cost of
clarity — I'd rather have more lines that read in order.

Clever and short is not the goal. The best version is the one a tired version of you understands at a glance in six months.

Fix the error handling

Find every place a failure disappears.

error-handling.txt
Audit the error handling in this: <paste>

Find:
- Empty catch blocks, and catches that only log then continue as if
  nothing happened.
- Errors caught too broadly, hiding ones I'd want to know about.
- Promises with no rejection handling.
- Failures that leave things half-done — a record created but not
  linked, a file written but not registered.
- Errors shown to users with internal detail in them.

For each: what actually happens today, what should happen, and whether
this failure should be retried, reported, or shown to the user.

A catch that logs and continues is a decision to proceed with broken state. Sometimes right, usually accidental, and worth making deliberately.

Comment the why, not the what

Most comments restate the code. The useful ones can't be inferred.

comments.txt
Here's my code: <paste>

Two passes:

1. Delete comments that just restate what the next line does. List
   what you removed.

2. Add comments only where something can't be inferred from the code:
   a non-obvious constraint, why the obvious approach doesn't work
   here, a workaround for an external bug, a magic number's origin,
   an ordering that matters.

If you don't know why something is the way it is, ask me rather than
inventing a reason. A wrong "why" comment is worse than none.

Wrong explanatory comments are actively harmful — people trust them and stop reading the code. Better to leave a question than a guess.

Make this testable

If it's hard to test, that's usually telling you something.

make-testable.txt
I can't easily test this: <paste>

Tell me what makes it hard to test — usually it's doing several things
at once, or reaching out to the world in the middle of its logic.

Then restructure it so the logic can be tested without the network,
the clock, the filesystem or the database. Keep the behaviour
identical.

Show me:
- The separated version.
- One test that would have been impossible before.
- What's still untestable and why that's acceptable.

Difficulty testing is a design signal, not a testing problem. A function that needs six mocks is a function doing six things.

Make it consistent with itself

Code assembled across many chats drifts in style.

consistency.txt
This project was built across many separate conversations and the
style has drifted: <paste several files>

Find the inconsistencies:
- Naming — camelCase here, snake_case there, different words for the
  same concept.
- Error handling done three different ways.
- Async handled with promises in one place and callbacks in another.
- Different patterns for the same kind of operation.

For each: pick one convention, say why, and list every place that
needs changing. Don't change anything yet — I want the list first.

Different names for the same concept is the costly one. Two words for one thing means every search misses half the code.

Can I drop this dependency?

Every one is code you ship without reading.

drop-dependency.txt
I use <package> for <what I use it for>. Here's how: <paste the usage>

Honestly: could I replace this with my own code?
- How much of the library am I actually using?
- What would the replacement look like — show me it.
- What edge cases does the library handle that I'd get wrong?
- Is it doing something genuinely hard, or something that's just
  tedious to type?

If keeping it is the right call, say so. I'm not looking to
reimplement date parsing.

The edge-case question decides it. A library you use 5% of but which handles time zones correctly is one you keep.

Modernise old async code

Callbacks to promises, without changing behaviour.

modernise-async.txt
This uses callbacks and I'd like promises and async/await: <paste>

Convert it, keeping behaviour identical:
- Errors that arrived as a first callback argument become rejections.
- Preserve the ordering. If operations ran sequentially, they must
  stay sequential — don't parallelise them as a "bonus".
- Anything that ran in parallel by accident, flag it rather than
  quietly changing it.
- Add the error handling the callback version was missing.

List every behavioural difference between the two versions, including
subtle ones around ordering and error timing.

The risk in this conversion is accidental parallelism. Code that happened to be sequential can develop race conditions the moment it isn't.

Write the rules file for my project

So every session and every agent starts with the same ground rules.

conventions-file.txt
I'm building <one sentence> with <stack>, deployed to <host>. Here's the
project as it stands: <paste the file list and one representative file>

Write a short conventions file for AI tools to read at the start of every
session, such as CLAUDE.md. Include:
- How to run it locally and how to deploy it to this host.
- The stack's conventions this project actually follows, taken from the
  code rather than from general advice.
- What's deliberately unusual here, and why.
- What must never happen: files not to edit, commands not to run.

Under 60 lines. Only things that can't be worked out from the code.

Every time you correct the model about the same thing twice, that correction belongs in this file.

Add a formatter and a linter

So style arguments stop and small mistakes get caught.

lint-setup.txt
My project uses <stack> and deploys to <host>. It has no linter or
formatter yet.

Set up the standard ones for this stack:
- Which tools, and why those.
- The smallest configuration that's useful. Defaults where possible.
- One command to format and one to check.
- Whether anything needs to change on the host, or whether this stays on
  my machine only.

Then tell me how to apply the formatter once, as its own commit, so it
doesn't clutter every later diff.

Format everything in a single commit on its own. Mixed with real changes, formatting hides the lines that matter in every diff for weeks.

Set up tests for my stack

One command, one test, running in under ten seconds.

test-setup.txt
My project is <one sentence>, built with <stack> and hosted on <host>.
It has no tests.

Set up the test tool people normally use with this stack:
- Installation, and the single command that runs everything.
- One real test of the thing I'd most hate to break: <describe it>.
- How to run a single test on its own.
- Whether tests need a database, and how to keep them away from the
  real one.

Tests run on my machine or in CI, never on the live host.

Point tests at a throwaway database from day one. A test suite that can touch production data will eventually do it.

Upgrade my runtime version

Moving to a newer language version without surprises on the host.

upgrade-runtime.txt
My project runs <stack> on <host>. I want to move to <new version>.

Plan the upgrade:
- What changed between my version and the new one that affects code like
  mine. Point at the patterns to search for.
- How to test locally on the new version before touching the host.
- How to switch the version on this host, and how to switch back.
- Dependencies that need updating first.

Give me a checklist in order, with a way back at every step.

Upgrade locally and run everything first. Switching the host's version and finding out live is how a quiet afternoon becomes an outage.

Make it read like good code in my stack

Generated code often works and still looks like a stranger wrote it.

idiomatic-review.txt
This code runs on <stack> and is deployed to <host>:
<paste>

Review it as an experienced developer in this stack would:
- Where does it ignore the stack's own conventions or built-in features?
- Where does it reinvent something the standard library already does?
- Anything that works locally but behaves differently on this host.

For each, show the idiomatic version. Don't change behaviour, and skip
pure style preferences.

Code that fights its own framework is harder for the next session to extend. Idiomatic code is also what the model has seen most often, so it edits it more reliably.