For months I typed the same prompts into Claude Code. “Review my staged changes for security issues.” “Write a commit message from the diff, focus on why not what.” “Summarize the last 5 commits in plain English.” Over and over. I even had them in a notes file that I’d copy-paste from.

Then I finally set up slash commands properly and felt stupid for waiting so long. A slash command is just a saved prompt you can trigger with /name. That’s it. No magic. But the difference between typing a 300-character prompt and typing /review is the difference between using something once a week and using it ten times a day.

Here are the ones that actually stuck for me. Not a list of 30 commands I wrote and never used. The handful I reach for constantly.


/review — the one I use most

This is my pre-commit sanity check. Before I stage anything, I run /review to catch the stuff I’d be embarrassed to push.

Review my uncommitted changes. Look for:
- Security issues (SQL injection, XSS, unvalidated input)
- Bugs that would fail at runtime (undefined access, wrong types)
- Logic errors (off-by-one, wrong condition, missed edge case)

Do NOT comment on:
- Formatting, style, or naming
- Minor nitpicks
- Preferences

Output a short list. If there's nothing, say "looks clean" and stop.

Two things make this work. The explicit “don’t” list keeps it from nitpicking about variable names. And the “if there’s nothing, say ‘looks clean’ and stop” line stops it from inventing issues to look useful. Without that, it’ll always find something to say, even when there’s nothing to find.

I catch real bugs with this weekly. Not every run. But often enough that I don’t ship without it.


/commit — commit messages that don’t suck

My commit messages used to be “update auth” and “fix bug.” Useful for nobody, including future me.

Read the staged diff. Write a commit message.

Rules:
- One-line subject, imperative mood ("Fix X" not "Fixed X"), under 70 chars
- Blank line, then 1-2 sentence body explaining WHY, not what
- Don't list files changed, I can see those
- If the change is trivial (typo, formatting), just write the subject line

The “WHY, not what” is the whole game. Anyone can read the diff to see what changed. A good commit message tells you why, which is the thing you’ll want to know six months from now when you’re bisecting to find when something broke.

I still edit about 30% of the messages. The other 70% I take as-is.


/explain — when I walk into a file cold

This is the one I wish I had when I joined my current job. You open a file you’ve never seen, and instead of reading it top to bottom trying to reverse-engineer the purpose, you just run /explain.

Explain the current file or the file path I give you.

Cover:
- What's the purpose of this module in one sentence
- The key exports and what they do
- Anything non-obvious (unusual patterns, hidden dependencies, gotchas)

Assume I know the language but don't know this codebase. Don't waste time on obvious stuff like "this imports React."

The “don’t waste time on obvious stuff” is critical. Without it, you get three paragraphs about the import statements before anything useful. With it, you get straight to the part that matters.

I use this for anything I’m nervous about changing. Saves me an hour of reading plus the embarrassment of breaking something subtle.


/impact — what will this break

I use this before any non-trivial refactor. If I’m going to rename a function, delete a file, or change an API, I want to know what depends on it.

Given what I'm about to change (ask me if it's unclear), find everything in the codebase that depends on it.

Include:
- Direct callers
- Type imports
- String references (in configs, env vars, URLs)
- Tests that would need to be updated

Return file paths and line numbers. If something is ambiguous (like a stringly-typed reference), flag it as "verify manually."

The “verify manually” flag saved me once. I was about to delete an unused API endpoint and /impact flagged three places it was referenced by string. Two were dead code. The third was a cron job I’d completely forgotten about. That endpoint was not, in fact, unused.


/test-gaps — find what isn’t tested

I don’t use this as often as the others, but when I do, it earns its spot.

Look at the current file and its test file (if it exists).

Identify:
- Public functions with no test coverage
- Error paths that aren't tested
- Edge cases the existing tests miss (empty input, negative numbers, null, etc.)

Don't suggest tests for trivial getters or simple passthroughs. Focus on logic worth testing.

The “don’t suggest tests for trivial getters” saved me from a dozen pointless tests. I don’t need a test that verifies user.name returns the name. I need tests for the thing that broke three weeks ago and the condition that would break it again.

I run this when I’m done with a feature but before I call it done. It’s almost always going to surface at least one real gap.


/why — git archaeology

This one is silly simple and I use it constantly.

For the current file (or the lines I specify), use git blame and git log to tell me:
- When this was last meaningfully changed (not formatting/rename)
- Who changed it and what the commit said
- Whether the related PR had useful context

If the history shows this file was churned on repeatedly, flag that — it usually means something is wrong with the design.

I used to manually run git log -p and scroll through, trying to find the commit that introduced some specific line. Now I just run /why and get a summary.

The “flag if churned repeatedly” bit is my favorite. I had a file that kept showing up in commits with messages like “fix bug in X,” “really fix X this time,” “actually fix X.” /why flagged it. That was the signal I needed to actually sit down and redesign the thing.


/stuck — when I’m not sure what I’m doing

This one is weird and I almost didn’t include it. But I use it more than I’d admit.

I'm stuck. I'll describe what I'm trying to do and what I've tried.

Don't give me code yet. Ask me 3-5 questions that will clarify what's actually going on. Focus on:
- What assumptions might I be wrong about
- What have I not told you that matters
- Is there a simpler way to think about this problem

After my answers, either suggest an approach or ask more questions.

This is the opposite of how I usually use Claude Code. Normally I want direct action. But sometimes I’m actually confused about the problem, not the code, and throwing more code at it won’t help.

The questions it asks are often the ones I should have asked myself first. Half the time I figure out the answer before even responding.


How I actually use them

Not all at once. I built these one at a time, over months, when I caught myself typing the same prompt for the third time. That’s the pattern I’d recommend: don’t try to design the perfect library of slash commands up front. Just notice when you’re repeating yourself, and turn that prompt into a command.

Also: keep them short and opinionated. A slash command that does five things badly is worse than a slash command that does one thing well. If I need two different kinds of review, that’s two commands, not one with flags.

And refine them over time. My current /review is maybe the fourth version. Each rewrite came from a run where the output wasn’t quite right and I realized the prompt itself was the reason. That tightness is the whole point.


Slash commands aren’t a feature I’d have built a product around. They’re just a quality-of-life thing. But they’re the difference between “Claude Code, the tool I open when I remember” and “Claude Code, the tool I use without thinking about it.” That shift mattered more than any specific command. If you’re still typing the same prompt twice, you’re leaving the best part on the table.