Find and reduce code duplication, clean up redundant code, detect code clones, reduce codebase size, DRY violations, copy-paste detection. Use when the user asks about duplicate code, code cleanup, reducing code size, DRY principles, or finding copy-pasted code.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Find and reduce code duplication, clean up redundant code, detect code clones, reduce codebase size, DRY violations, copy-paste detection. Use when the user asks about duplicate code, code cleanup, reducing code size, DRY principles, or finding copy-pasted code.
argument-hint
[path or extension]
Prerequisites
Before running quickdup, check if it is installed:
From source: go install github.com/asynkron/Asynkron.QuickDup/cmd/quickdup@latest
About QuickDup
QuickDup is a fast structural code clone detector (~100k lines in 500ms). It uses indent-delta fingerprinting to find duplicate code patterns. It is designed as a candidate generator — it optimizes for speed and recall, surfacing candidates fast for AI-assisted review.
Results are written to .quickdup/results.json and cached in .quickdup/cache.gob for fast incremental re-runs.
Workflow
Run quickdup to find duplication candidates
Review the results with -select to inspect specific patterns
Classify each pattern — determine which type of duplication it is (see below)
Refactor using the right pattern — not all duplication should be removed the same way
Re-run to verify duplication is reduced
Determine File Extension
Before running, determine the primary language/extension of the project. Look at the files in the target path and use the appropriate -ext flag (e.g. .go, .ts, .cs, .py, .java, .rs).
Common Usage
Scan current project:
quickdup -path . -ext .go
Scan with specific extension (adapt to project language):
normalized-indent (default) — indent deltas + first word per line
word-indent — raw indentation + first word
word-only — ignores indentation, first words only
inlineable — detects small patterns suitable for inline extraction
Suppressing Known Patterns
If a pattern is intentional duplication, suppress it by adding its hash to .quickdup/ignore.json:
{"description":"Patterns to ignore","ignored":["56c2f5f9b27ed5a0"]}
How to Refactor Duplicated Code
QuickDup finds duplication candidates. The next step is knowing how to fix them. Not all duplication is the same — each type has a different refactoring strategy.
Type 1: Structural Duplication with Contextual Variation
Two blocks share the same control flow and structure, but differ in injected behavior (which function is called, which parameters are passed, whether some context like an index exists).
How to recognize it:
Same loops, same branching, same method calls in the same order
Only the behavior inside the structure differs
How to refactor:
Ignore the differences — mentally replace the differing lines with placeholders. If the code still "reads the same", you have structural duplication.
Identify the invariant structure — same loops, branching, method calls in the same order. That is the structure to extract.
Identify the varying behavior — what methods differ? What parameters differ? What context exists in one version but not the other? These become delegates, lambdas, or strategy objects.
Extract, do not merge — do NOT write if (variant) { ... } else { ... }. Instead, extract the shared structure and pass behavior in.
Preserve meaning at call sites — the call site should still clearly express intent.
Good:
IterateAndResolve(array, i => CreateResolve(i), ...)
Bad:
IterateAndResolve(array, withIndex: true)
Rule of thumb: If two methods differ only in what they do inside a shared structure, extract the structure. If they differ in structure, keep them separate.
Type 2: Structural Switch Duplication
Repeated switch/pattern match blocks on the same domain structures. Common in AST walkers, serializers, interpreters, and compilers.
How to recognize it:
Repeated switch or pattern matching blocks
Short, trivial case bodies
Each case extracts or forwards structure
No real algorithm, just classification
When to leave it alone:
Each case is one or two lines
The code is stable and unlikely to drift
The abstraction would just wrap a switch
The switch documents the domain shape — removing it hides meaning
Rule of thumb: If the switch describes structure, duplication is documentation. If the switch implements behavior, consider extraction.
Type 3: Parameter Bundle Duplication
The same set of context values passed together in multiple places — same parameters, same order, same meaning.
How to recognize it:
Same group of 4+ parameters passed together repeatedly
Usually forwarded to constructors or methods
Reads like a "context snapshot"
Adding a new parameter would require editing many call sites
How to refactor:
Extract a value object:
new ExecutionContext(thisValue, realmState, isStrict, homeObject, privateScope)
Then pass the single object instead of 5+ individual arguments.
When to leave it: Appears only once, is highly localized, or has extremely short lifetime.
Rule of thumb: If the same parameter list appears 2-3+ times, it wants to become a named type.
Type 4: Argument Unpacking Duplication
Duplicated defensive parsing of callback arguments — same local variables, same guards, same positional decoding.
How to recognize it:
Same argument index checks (args.Count >= 1, args[0])
Same type unwrapping logic
Same local variable names
Appears inside lambdas, which amplifies the noise
How to refactor:
Extract a small helper whose only job is to unpack the arguments:
UnwrapResolveReject(args, out var resolve, out var reject);
This is purely mechanical code — the intent is obscured by boilerplate, and any bug fix would need to be applied to every copy.
Rule of thumb: If you copy the same argument decoding logic twice, extract it. If the extraction reads like English, you picked the right abstraction.
Guidelines
Always determine the correct -ext for the project before running
Start with defaults, then tighten -min-similarity if too many false positives
Use -select 0..5 to inspect the top candidates before refactoring
After identifying duplicates, classify them by type before refactoring
Not all duplication should be removed — structural switch duplication is often intentional documentation
After refactoring, re-run to confirm duplication is reduced
For large projects, quickdup caches results — subsequent runs are near-instant
When the user wants to clean up or reduce code size, run quickdup first to identify targets, then refactor the highest-scoring patterns using the appropriate strategy for each type