Most write-ups of Claude Code's /simplify get its scope wrong, and the scope is the whole story. /simplify is not a whole-repo refactoring engine you point at legacy code. It reviews the code you just changed (your working diff), looks only for quality improvements, and then applies the fixes itself. Diff-scoped, quality-only, self-applying. Once you understand those three constraints, you understand both why it works and when it will disappoint you. I run it on a production Laravel codebase; here is what that actually looks like.

What /simplify Actually Does (and Does Not)
From daily use, the contract is precise:
- It reviews changed code for four things: reuse (code that duplicates something that already exists), simplification, efficiency, and altitude cleanups, meaning logic that sits at the wrong level of abstraction.
- It is quality-only. It explicitly does not hunt for bugs. Correctness review is a different command in my workflow (
/code-review), with its own effort levels. Treating/simplifyas a bug-finder is the most common mistake I see. - It applies the fixes to the working tree instead of handing you a list of suggestions to implement manually.
The diff scoping is the underrated design decision. Because it only examines what changed, it runs fast, its context stays small, and its suggestions stay relevant to the work you are actually doing, instead of nominating your entire codebase for a rewrite you will never do.
Real Passes on Real Laravel Code
These are the categories of fix /simplify produces on my codebase, with the shape of each before/after.
Trait extraction from duplicated Livewire logic
Two Livewire components had grown near-identical concerns independently, the way duplication always happens: one feature at a time, each addition locally reasonable. The simplify pass flagged the duplication because the diff touched one of the twins, then extracted the shared behavior into a trait both components use. This is textbook senior-review feedback, and it appeared without me asking for it.
Batch inserts replacing loops
A loop calling Model::create() per row became a single bulk insert. On a content site where import and translation scripts touch hundreds of rows, this is the difference between a script you run and a script you babysit. The pass caught it because the loop was in the diff, not because it audited the whole app for N+1 patterns.
Blade templates collapsing into partials
A view that had accumulated three visually identical card markups became one partial with three includes. Notably, /simplify found the existing partials directory convention and followed it, rather than inventing a new components structure, because reuse means reusing what the project already has.
Early returns over nested conditionals
The classic. Guard clauses replacing arrow-shaped if nesting. Small, but it compounds across every review.
The Insight: /simplify Obeys Your CLAUDE.md
Here is the thing I have not seen anyone else write about, and it changed how much I trust this feature. "Simpler" is not a universal constant, and a naive simplifier will happily strip things your project needs. My project's CLAUDE.md contains explicit guardrails, written after near-misses:
- Keep Filament's
->helperText()and->hint()calls. They look like ceremony; they are UX. - Never strip
->translateLabel(). It looks redundant; it powers a six-locale setup. - Form Request validation stays even where Filament also validates, because my API routes reuse the same request classes.
With those rules in the project memory, /simplify respects them. Without them, "simplification" would have quietly deleted load-bearing code that only looks decorative. So the real setup for this feature is not installing it; it is writing down what your project considers essential complexity. The skill defines simple; your CLAUDE.md defines sacred.
This also explains when /simplify disappoints people: run against a project with no documented conventions, it can only apply generic taste. Generic taste over-DRYs. Two similar-looking blocks get merged even when they are similar by coincidence and about to diverge. Knowing when not to abstract is a judgment I still keep for myself, a point I have argued before in restraint is the most important dev skill.
Where It Fits in a Real Workflow
My loop, in order:
- Build the feature. Let the first draft be a bit rough; that is what drafts are for.
- Run
/simplifyon the uncommitted changes. - Review its diff. I accept most reuse and early-return fixes as-is and read abstraction changes carefully.
- Gate with the project's actual quality tools:
vendor/bin/pintfor formatting, PHPStan level 8 for types, then the relevant PHPUnit tests. - Commit.
Step 4 is non-negotiable and it is also the answer to "can I trust an AI applying refactors?" You do not trust it. You verify it, mechanically, with the same pre-commit gates that catch your own mistakes. On my repo a git hook enforces Pint before any commit lands, so a simplify pass that broke formatting or types would be stopped by machinery, not vigilance.
For deeper structural work (module boundaries, deep-vs-shallow interfaces), a diff-scoped pass is the wrong altitude entirely; that is a separate practice I covered in improving codebase architecture with the deep-modules skill. And for the general problem of AI-generated code accumulating cruft, there is a whole ecosystem of cleanup tooling I compared in tools that fix Claude Code AI slop.
Honest Assessment After Months of Use
Worth it? Yes, with one reframe. The value is not dramatic percentage reductions in line count; headline numbers like that depend entirely on how messy the diff was to begin with. The durable value is that every feature now gets a competent quality review before commit, at the moment it is cheapest to act on, with zero scheduling overhead. It is the same compounding logic as other buried features I use daily, several of which I collected in Claude Code features most developers never find.
Not worth it when: the diff is trivial (formatting-level changes need Pint, not a model), or the code is exploratory and about to be thrown away. Polishing a prototype is how prototypes become permanent.
The command is the easy half. The hard half is judgment — when to accept an AI refactor, when to override it, and how to write down what your project treats as sacred so the tooling respects it — and that judgment layer is the spine of the courses in my AI School, taught against working systems instead of demos.