What counts as a duplicate
A match must span at leastduplicateBlockMinTokens normalised tokens, 40 by default. Consecutive matching windows merge into one block, so a long copy reports once rather than as shifted fragments.
The remaining rules exist to keep the results reviewable:
- Import headers never match. Two files importing the same components is not technical debt, and reporting it would bury the real findings.
- Uniform data literals never match. Country lists and enum tables are structurally identical by nature.
- No pairwise explosion. A block appearing eight times reports as the minimal set of pairs covering it rather than all 28 combinations, and contained sub-matches are dropped.
- Markup requires more evidence. In
.jsx/.tsx, or.jscontaining JSX, the token threshold doubles, since JSX is structurally repetitive by design. - Oversized or minified-looking files are excluded from comparison, and the exclusion is disclosed rather than applied silently.
Where you’ll see it
File tab shows within-file blocks as a “Duplicate blocks” smell with both locations. Each block deductshealthScoreWeights.duplicateCode points, 3 by default.
Workspace and Folder tabs include a Duplication section: the block count, the percentage of code lines duplicated, and the largest blocks with click-through to either location.
The Duplicates table, behind “See all”, is filterable by cross-file or within-file, searchable, and both locations are clickable. It tracks live edits, so ranges update as you type and resolved pairs drop out without a rescan.
The diff view (Pro)
Every row has Open diff, titled with both sides the way GitHub would:scanner.ts:10-24 ↔ parser.ts:88-102.
Cross-file pairs open both real files side by side, scrolled to their blocks, fully editable and saved normally. You are editing the actual files with their full context visible, and Iris Code confirms with a notification once the duplication is resolved.
Same-file pairs would show nothing useful in a self-diff, so they open as two editable extracts instead. Saving a pane writes the change back into the real file, an Open link jumps to the full file, and the panes update as the file changes.
Gating on duplication (Pro)
gateMaxDuplicateBlocks caps the total number of duplicate blocks across the scan, enforced by iris check, iris gate, the pre-push hook and the build hook. A block spanning two files counts once.
.irisconfig.json
iris gate shows a “Max duplicate blocks” rule row and lists the files involved on failure.
Configuration
See the .irisconfig.json reference for the full config surface.
Suppressing a finding
duplicate-code is a suppressible rule id, with the usual required reason:
In the CLI
iris check --format json adds a duplicateBlocks array to each file entry, and iris gate discloses any files excluded from comparison.