DEV Community

Cover image for 10 Claude Code commands that actually changed how I ship
<devtips/>
<devtips/>

Posted on

10 Claude Code commands that actually changed how I ship

I was re-typing the same prompts from memory every day. Then I found out Claude Code had a whole command system I’d been ignoring for months.

You know that moment when you realize the tool you’ve been using for half a year has a feature that would’ve saved you hundreds of hours and it was in the docs the whole time? Yeah. That’s this article.

I’d been running Claude Code daily since early 2025. Writing prompts, getting code, copy-pasting, repeat. Classic vibe coding loop. What I didn’t realize was that I was basically driving a sports car in first gear the entire time. Every code review, I’d retype the same 12-line checklist. Every new component, same scaffold instructions. Every commit, same “write me a conventional commit message” prompt from memory slightly different each time, slightly worse output each time. Turns out there’s a name for that: prompt drift. And it quietly tanks your results without you ever noticing.

Claude Code has a slash command system that lets you save any prompt as a reusable command, version-control it with your team via Git, and fire it with a single /command-name. It's been there the whole time. Most devs skip it because nobody told them it existed.

So this is that article. No fluff, no “AI will 10x your productivity” nonsense just 10 commands, what they actually do, real code you can drop into your project today, and the specific moments they saved me from myself.

Here’s what’s coming:

  • How slash commands work (and the 4-minute setup you’ll actually do)
  • Commands 1–3: The daily drivers you’ll use every single session
  • Commands 4–6: The workflow multipliers that kill repetitive grunt work
  • Commands 7–9: The power moves most devs don’t know exist
  • Command 10: The team play that ended merge conflicts for a full sprint
  • Resources, links, and the full repo to steal everything

Let’s go.

How slash commands actually work (set this up first)

Before the commands, two minutes of context because this tripped me up early and I don’t want it to trip you up.

Claude Code has two different things that look identical but aren’t: built-in slash commands and custom slash commands. Built-ins are hardcoded into the CLI things like /clear, /compact, /help, /diff. They just exist. Custom commands are markdown files you create yourself that become slash commands. That's the system we're mostly talking about today.

To create a custom command, you drop a .md file into one of two folders:

# Project-scoped — shared with your team via Git
your-repo/.claude/commands/preflight.md → /preflight
# User-scoped - personal, works across all your projects
~/.claude/commands/orient.md → /orient
# Subdirectories create prefixed commands
.claude/commands/db/migrate.md → /db:migrate

The filename becomes the command name. The file content becomes the prompt. That’s the whole system. Stupidly simple once you see it.

You can optionally add YAML frontmatter at the top to pre-approve tools (so Claude stops asking permission on every git call), pin a model, or add a description:

---
description: Pre-commit check for debug artifacts and code smells
allowed-tools: Bash(git ), Bash(grep ), Read, Glob
model: claude-sonnet-4-6
---

And if you need dynamic input like passing a filename or a ticket number use $ARGUMENTS:

/fix-issue 142 high
# In your .md file:
Fix issue #$1 with priority $2. Check the issue description
and implement the necessary changes.

One more thing worth knowing: Anthropic merged the old .claude/commands/ system with a newer .claude/skills/ system. Your existing command files still work fine, but new ones should go in .claude/skills/ if you want access to newer features like shell-injected context and agent configuration. For everything in this article, either location works.

Setup time is genuinely four minutes. Create the folder, add your first .md file, type / in Claude Code and watch it appear in autocomplete. Once you see it, you can't unsee it.

Now the actual commands.

Commands 1–3: The daily drivers

These three you’ll use every single session. If you only set up three commands from this entire article, make it these.

Command 1: /init give Claude a memory

Every time you start a fresh Claude Code session, it has zero context about your project. No idea what your build command is, what conventions you follow, what folders matter. So it scans. It reads. It figures things out from scratch, eating your tokens and your time before you’ve even asked it anything useful.

/init fixes this. Run it once in a new project and it generates a CLAUDE.md file a persistent memory file that Claude reads at the start of every session automatically.

# CLAUDE.md

## Project overview
FastAPI inference service with scikit-learn models and Alembic migrations.
## Key commands
- make dev - start local server
- make test - run pytest suite
- make lint - black + ruff
## Conventions
- All endpoints return typed Pydantic models
- Never commit directly to main
- Migrations live in /alembic/versions

You can edit this file manually after generation and you should. The more specific it is, the less Claude wastes time figuring out context that you already know. Think of it as your project’s onboarding doc, except the new hire is an AI that reads at the speed of light and forgets everything between sessions.

Reference: CLAUDE.md explained Shipyard

Command 2: /compact save your context window before it saves you

Here’s a thing that happens to everyone once: your session gets long, Claude starts referencing variables that don’t exist, suggests refactors you already did an hour ago, and generally acts like it’s been awake for 30 hours. That’s context window overflow. The conversation history got too big and it’s degrading the outputs.

/compact compresses the conversation history keeps the important stuff, strips the redundant back-and-forth, and gives you clean working memory again.

# Basic compact
/compact

# Compact with focus instruction - keeps specific context
/compact focus on the auth refactor, ignore the CSS discussion

The trick is using it proactively, not reactively. Don’t wait for Claude to start hallucinating. Run it before switching to a new phase of work within the same session. I run it roughly every 45 minutes on long coding days.

Command 3: /review automated PR review that actually finds bugs

/review triggers a code review of your recent changes. Out of the box it's useful, but out of the box it's also extremely chatty it'll write a paragraph about your variable naming while missing the actual logic error two lines below.

The fix is a claude-code-review.yml override file that tightens the prompt. This is the one the Builder.io team landed on after their default review was "way too verbose":

# .claude/claude-code-review.yml
direct_prompt: |
Review this pull request and look for bugs and security issues only.
Do not comment on style, naming, or formatting.
Be concise. Only report what you actually find.

With that config in place, /review stops being a noisy linter and starts behaving like a senior dev who skips the lectures and just spots real problems. It catches logic errors. It catches security gaps. It doesn't care that you named a variable data.

If you’re on a team and your PR volume is climbing because of AI-assisted development and it probably is this command pays for itself inside a week.

Commands 4–6: The workflow multipliers

These are the commands that kill the grunt work. The stuff that isn’t hard, just annoyingly repetitive and repetitive tasks are exactly where prompt drift quietly destroys your consistency.

Command 4: /commit-msg never write a commit message again

Show of hands: how many of your last ten commit messages were some variation of “fix bug”, “update”, or “wip”? Yeah. We’ve all been there. And if you’re on a team that actually enforces conventional commits, you’ve probably spent a non-trivial portion of your career typing feat(auth): before a sentence you half-thought through.

Create this file at .claude/commands/commit-msg.md:

---
description: Generate a conventional commit message from staged changes
allowed-tools: Bash(git diff --staged), Bash(git log --oneline -5)
---

Read the staged diff and the last 5 commits for context.
Generate a conventional commit message following this format:
<type>(<scope>): <short summary>
Types: feat, fix, refactor, test, docs, chore, perf
- Summary must be under 72 characters
- Use imperative mood ("add" not "added")
- If breaking change, append ! after type/scope
- Output only the commit message, nothing else

Now run /commit-msg after staging your files and Claude reads the actual diff, understands the scope, and writes the message. Not from memory. Not from vibe. From the code.

My commit history went from “fix stuff” to something a PM could read and a changelog generator could parse. It felt like cheating for about two days and then it just felt normal.

Command 5: /scaffold boilerplate at warp speed

Every project has patterns. A React component always needs the same basic structure. An Express route always gets the same middleware stack. An API handler always needs the same error boundary. You know this. You’ve written it four hundred times.

/scaffold is a custom command where you encode your project's patterns not some generic template from the internet, but the actual conventions your codebase uses and generate new files that already fit.

Create .claude/commands/scaffold.md:

---
description: Scaffold a new component or module following project conventions
allowed-tools: Read, Write, Bash(ls src/)
argument-hint: [type] [name] [--tests] [--stories]
---

Scaffold a new $1 named $2 following the existing patterns in src/.

Before generating, read 2-3 existing $1 files to match conventions exactly.
If --tests flag is passed, generate a test file alongside it.
If --stories flag is passed, generate a Storybook story file.

Match: naming conventions, import style, export pattern, folder structure.
Do not invent patterns that don't exist in the codebase.

Then fire it:

/scaffold react-component UserProfile --tests --stories
/scaffold express-route /api/payments --tests
/scaffold db-model Subscription

The key line is “read 2–3 existing files to match conventions exactly.” That’s what makes this different from every other scaffold tool it learns from your actual codebase instead of generating code that looks slightly off and needs four manual edits before it fits.

Reference: claude-code-tresor commands library

Command 6: /test-gen from 28% coverage to something respectable

Test coverage is one of those things every dev agrees matters and approximately nobody enjoys actually writing. The work is tedious, the feedback loop is slow, and there’s always something more interesting to build. So coverage sits at 28% for six months while everyone silently agrees not to mention it in standup.

Create .claude/commands/test-gen.md:

---
description: Generate comprehensive tests for a given file
allowed-tools: Read, Write, Bash(cat package.json)
argument-hint: [filepath] [--framework] [--coverage-gaps]
---


Generate tests for $1.
First, read the file and identify: exported functions, edge cases,
error paths, and any integration points.
Check package.json to confirm the test framework in use.
If --coverage-gaps is passed, run existing tests first and only
generate tests for uncovered paths.
Follow the existing test style in the tests folder.
Do not test implementation details - test behavior.

Usage:

/test-gen src/utils/auth.ts --framework vitest
/test-gen src/api/payments.ts --coverage-gaps

The --coverage-gaps flag is the real unlock. Instead of generating redundant tests for already-covered paths, it reads what exists and fills the holes. Pointed this at a legacy utils folder on a Friday afternoon. Coverage went from 28% to 71% before I closed my laptop. First time I've ever looked forward to writing tests because I wasn't really writing them.

Commands 7–9: The power moves

These three are the ones most devs never discover because they’re not in any getting-started guide. They’re also the ones I’d miss most if they disappeared tomorrow.

Command 7: /security-check your own security scanner, always on

Security audits are one of those things teams either do religiously or completely skip depending on whether someone got burned recently. The problem with the “wait until it hurts” approach is obvious in retrospect and invisible in the moment.

This command runs a focused security scan on your codebase every time you want it no external service, no SaaS subscription, no waiting for a quarterly audit.

Create .claude/commands/security-check.md:

---
description: Scan codebase for common security vulnerabilities
allowed-tools: Read, Grep, Glob
model: claude-opus-4-6
---


Analyze the codebase at $1 (or current directory if no argument) for:

- SQL injection risks (raw queries, unparameterized inputs)
- XSS vulnerabilities (unsanitized user input in rendered output)
- Exposed credentials (hardcoded keys, secrets in non-.env files)
- Insecure configurations (debug mode in prod, open CORS, weak auth)
- Dependency confusion risks in package manifests

For each issue found:
1. Show the exact file and line number
2. Explain why it's a risk
3. Suggest the specific fix

If nothing is found, say so clearly. Do not invent issues.

Usage:

/security-check src/api
/security-check . # scans everything

Two things worth noting. First, the model: claude-opus-4-6 pin — this is the one command where you want the smartest model on the job, not the fastest. Security reasoning is exactly the kind of nuanced, multi-step analysis where Opus earns its cost. Second, the "do not invent issues" line at the bottom is load-bearing. Without it, Claude occasionally hallucinates vulnerabilities in clean code. Guardrails in prompts matter.

Reference: Anthropic slash commands docs

Command 8: /rewind the undo button for your entire session

This one’s a built-in, not a custom command and it might be the most underrated thing in Claude Code.

Here’s the scenario: Claude misunderstands your intent, goes down a rabbit hole, and refactors three files you didn’t ask it to touch. You come back from grabbing coffee and the codebase looks like it had an argument with itself. Now you have to figure out what changed, manually revert files, and re-explain your original intent from scratch while Claude carries the wrong context from the previous exchange.

/rewind handles all of that in one command. It reverts both the conversation history and the file changes back to a previous checkpoint implicit checkpoints that Claude creates as you work.

/rewind
# Opens interactive checkpoint picker — select how far back to go

The workflow that actually works:

# 1. Ask Claude to attempt something risky
# 2. Review with /diff before accepting
# 3. If it went sideways → /rewind back to before the attempt
# 4. Rephrase the prompt with more constraints
# 5. Try again

I used to waste 30–45 minutes manually reverting bad sessions and re-establishing context. Now it’s a 10-second /rewind and a better prompt. The number of times this has saved a late-night session from becoming a full rollback is embarrassing to admit.

Reference: batsov.com essential Claude Code commands

Command 9: /diff catch mistakes before they compound

Also built-in. Also criminally underused.

/diff opens an interactive viewer showing every single file change Claude has made in the current session. Not just the last change everything, across all files, since the session started.

/diff
# Interactive viewer: scroll through all changes, file by file

The reason this matters is compounding. Claude makes a small wrong assumption in step 2, builds on it in step 4, builds on that in step 7, and by step 9 you have a structurally coherent but fundamentally misaligned set of changes that are painful to unpick. Each individual edit looked fine in isolation. The sum of them drifted from what you actually wanted.

The practice that fixed this for me: run /diff before every /commit-msg. Every time, without exception. It takes 90 seconds and it's caught at least a dozen "wait, why did it touch that file" moments that would've shipped as bugs.

Think of it as a mandatory code review with yourself before anything reaches Git. Not glamorous. Genuinely important.

# The rhythm that works:
/test-gen src/feature.ts
# ... Claude writes tests ...
/diff # review everything before committing
/commit-msg # generate message from clean, verified diff
git commit -m "$(pbpaste)"

Command 10: /preflight the team play that ended merge conflicts

This one’s a custom command but it thinks like a system. It’s not doing one thing it’s doing everything your team agreed should happen before code touches the remote branch, automated into a single slash command that runs the same way every time for every person on the team.

Create .claude/commands/preflight.md:

---
description: Full pre-commit check — lint, types, debug artifacts, code smells
allowed-tools: Bash(git ), Bash(grep *), Bash(make ), Read, Glob
---

Run a full preflight check before committing. In order:
1. Scan staged files for debug artifacts:
- console.log, debugger, TODO, FIXME, hardcoded localhost URLs
- Report file + line number for each hit

2. Run linter: make lint
- If it fails, show only the errors, not the full output

3. Run type check: make typecheck
- If it fails, show the first 10 errors only

4. Check for obvious code smells:
- Functions over 50 lines
- Deeply nested conditionals (4+ levels)
- Duplicate logic blocks over 10 lines

5. Final summary:
- ✅ if all checks pass - safe to commit
- ❌ list of what failed and where - do not auto-fix anything

Do not make any changes. Report only.

The last two lines are critical. This command is an observer, not an actor. It tells you what’s wrong, you decide what to fix. Giving an automated pre-commit command write access to your staged files is how you end up with a codebase that fixed itself into a broken state.

The team impact is the real story here. When this command lives in .claude/commands/ and gets committed to Git, every developer on the team runs the exact same preflight check. Same lint rules, same type check, same artifact scan, same code smell thresholds. No more "it passed on my machine." No more forgotten console.log that makes it to staging. No more merge conflicts because two people formatted the same file differently.

Zero merge conflicts last sprint. First time in 18 months. I’m not saying /preflight is entirely responsible for that but it's not not responsible either.

Wrapping up: your prompts are code now, treat them that way

Here’s the thing that took me too long to fully internalize: the way you use Claude Code is a skill that compounds. Every command you write, version-control, and share with your team is a permanent improvement to how your entire team ships. It doesn’t reset when you close the terminal. It doesn’t drift when someone new joins. It just works, every time, the same way.

Most devs are still using Claude Code like a chatbot with a terminal window. That’s not a criticism it’s just where the default usage pattern lands. But there’s a real gap between “using Claude Code” and “building a command library that encodes your team’s best practices into reusable, version-controlled workflows.” The teams on the right side of that gap are shipping noticeably faster, with fewer regressions, and with less tribal knowledge living inside individual developers’ heads.

The slightly uncomfortable take: in a year or two, your .claude/commands/ folder is going to matter as much as your dotfiles. It's going to be one of the first things you clone when you set up a new machine. Devs will share command libraries the way they share vim configs today obsessively, opinionatedly, and with strong feelings about the right way to do it.

So start building yours. Start small one /preflight, one /commit-msg, one /review override. Get it into Git. Share it with your team. See what happens to your sprint velocity.

What’s your most-used custom command? Drop it in the comments I’m genuinely curious what workflows people are encoding that I haven’t thought of yet.

Helpful resources

Top comments (0)