
Minimal repros are key to debugging, both by yourself abnd with others.
- It is minimal. This means it contains the least amount of details that are sufficient. Anything can that can be removed, is removed.
- It reliably reproduces the issue. "If you follow these steps exactly, you too will see the issue."
First-and-foremost, you make repros for you.
You can't fix what you can't repro: how would you know if you even fixed it? This point is profound, so let me spell it out for you:
- You have a bug
- You don't first establish a repro.
- You try to fix the bug.
- Now what? Did you even fix the bug? How can you tell?
This is similar to the maxim that you should never optimize without first measuring. If you try to make something faster without first measuring how fast it is, how will you know if you succeeded or made things worse? More importantly: how will you make sexy graphs you can post online to brag about your achievement?
Debugging is isolating. You cannot address what you cannot isolate. How can you fix a bug if you don't know where it is.
The XY Problem: Sometimes while making a minimal repro, you'll realize you're solving the wrong problem entirely. You thought you had a CSS bug, but actually you're fighting the browser's default styles. Read more about the XY Problem →
When you ask for help with a messy, complex codebase, you're essentially saying: "Here's my whole room. Find my keys."
A minimal repro says: "Here are my keys on an empty table. Why won't they turn?"
Asking someone to isolate your bug for you is like asking a painter to clean your room before they can paint the walls. That's your job. The isolation work is the prerequisite to getting help—not part of the help itself.
People who help in forums, Discord servers, and GitHub issues are volunteering their time. Respect it.
Got ChatGPT, Claude, or Copilot? A minimal repro is perfect for pasting into an AI assistant.
The smaller and more focused your code, the better the AI can understand and help. A 2000-line file will confuse it. A 20-line reproduction will get you a precise answer. Minimal repros aren't just for humans anymore.
A great repro puts the other person into the bug as fast as possible. Here's what that looks like:
Write out the exact steps. Don't assume anything is obvious.
Example of good steps
- Go to the login page
- Enter any email address
- Leave password blank
- Click "Submit"
- Expected: Validation error appears
- Actual: Page crashes with white screen
Include the context that helps diagnose:
- Error messages — Copy the full text, not just "it says error"
- Console logs — Open DevTools (F12) → Console tab
- Network requests — DevTools → Network tab (look for red/failed requests)
- Crash reports — Stack traces, error codes, anything the system tells you
- Incognito test — Try in a private/incognito window to rule out browser extensions
Tools that capture this automatically
- Jam.dev — Captures console logs, network requests, and more in one click
- Browser DevTools — Your built-in best friend
- Screen recording with voiceover — Walk through what you're seeing
A video of you recreating the issue while talking through it is incredibly valuable. Describe:
- What you're clicking
- What you expect to happen
- What actually happens
The absolute best repro is one someone can run instantly:
- JSBin / CodePen / JSFiddle — For frontend issues
- Val Town — For backend/API issues
- TypeScript Playground — For TypeScript type issues
- Rollup REPL — For bundler issues
- GitHub repo — For complex setups (but keep it minimal!)
If someone can click a link and see your bug, you've done the work for them.
❌ Bad bug report
"The app is broken. When I click the button nothing happens. Please fix ASAP."
What's wrong with this?
- No steps to reproduce
- No error messages
- No expected vs actual behavior
- No environment info
- "Nothing happens" could mean 100 different things
✅ Good bug report
Environment: Chrome 120, macOS Sonoma, Node 20.10.0
Steps:
- Open the dashboard (
/dashboard)- Click "Export Data" button
- Select "CSV" format
- Click "Download"
Expected: CSV file downloads
Actual: Nothing happens. Console shows:
TypeError: Cannot read property 'map' of undefined at ExportService.js:42Minimal repro: [CodeSandbox link]
Notes: Works fine with "JSON" format. Only fails with CSV.
Why this is better:
- Exact steps anyone can follow
- Clear expected vs actual
- Full error message with line number
- Environment specified
- Narrowed down to CSV-specific issue
- Includes runnable reproduction
- Create a new project/file/sandbox
- Add only the code needed to show the bug
- If you can't reproduce it, that tells you something!
- Make a copy of your project
- Delete half the code
- Does the bug still happen?
- Yes: Delete half of what remains
- No: The bug was in what you deleted—put it back and delete the other half
- Repeat until you have the smallest possible code that shows the bug
Another similar debugging technique is git bisect until you find the offending
commit.
What to remove first
- Unrelated features and buttons
- Styling and CSS (unless it's a styling bug)
- Authentication and API calls (replace with hardcoded data)
- Extra dependencies
- Comments and dead code
- Configuration files (use defaults)
Somewhere in this process, you'll often go: "Wait, why did I write it that way?"
That's the magic. The minimal repro process forces you to understand your own code. And understanding is 90% of fixing.
Sometimes context matters. A minimal repro might not capture:
- Race conditions — Timing-dependent bugs that only appear under load
- Environment-specific issues — Bugs that only occur on specific OS/browser/hardware combinations
- Security vulnerabilities — Where the full context is needed to understand the attack vector
- Data-dependent bugs — Issues that only appear with specific data shapes or volumes
In these cases, be upfront: "I couldn't reproduce this in isolation, but here's what I've tried..." and provide as much context as you can about when/how it occurs.
TODO - would be nice here to mention heisenbugs.
Before sharing your repro, verify each item. Click any item to link directly to it.
- Self-contained — Can someone copy-paste-run it without setup?
- Include the error — Full error message, not "it doesn't work"
- Include versions — Node version, browser, OS, package versions
- Steps to reproduce — Numbered list of exactly what to do
- Expected vs Actual — What should happen? What happens instead?
- Actually minimal — Could you remove anything else? Try.
- No screenshots of code — I can't copy-paste an image. Give me text.
- No partial code — "Here's the relevant part" often hides the bug
- No entire codebases — Your 50-file project isn't a repro
- "It doesn't work" — Doesn't work how? What did you expect?
- Nothing is "obvious" — State your environment, steps, everything
- 📚 SSCCE — The original guide that inspired this page
- 🐛 Jam.dev — Capture bug reports with full context
- 📖 How to Report Bugs Effectively — Simon Tatham's classic guide
repro.fyi — Because debugging is isolating, and isolating is your job.
Found this helpful? Share it with someone who sends you "it's broken" messages.
Have feedback or want to contribute? Edit this on Val Town →