Changelog
Overview
For the full, up-to-date changelog, see the jscpd GitHub repository.
v5.0.4 (Latest)
The Rust Rewrite
jscpd v5 is a complete Rust rewrite — a self-contained native binary that delivers 24-37x faster detection with zero Node.js dependency.
Detection Speed
| Target | Files | Size | v4 (Node.js) | v5 (Rust) | Speedup |
|---|---|---|---|---|---|
| fixtures | 548 | 1.5 MB | 1.03s | 0.03s | 34.3x |
| Svelte | 8,963 | 38 MB | 15.80s | 0.43s | 36.9x |
| CopilotKit | 17,092 | 159 MB | 82.89s | 3.44s | 24.1x |
Benchmarked on macOS (Apple Silicon), 10 runs for fixtures/Svelte, 3 for CopilotKit.
Git Blame Speed
The --blame flag enriches clones with git author data. v5 uses gitoxide for in-process blame instead of shelling out to git per file.
| Target | v4 --blame | v5 --blame | Speedup |
|---|---|---|---|
| fixtures (548 files) | 3.57s | 0.13s | 27.5x |
v4's blame mode is 3.5x slower than its own non-blame mode (3.57s vs 1.03s). v5's blame adds only ~0.10s (0.13s vs 0.03s).
See the Migration Guide for the full benchmark details.
New Features
- Native binary — no Node.js runtime required. Install via
npm install -g jscpd,cargo install jscpd, or direct download. - 13 reporters — console, console-full, json, xml, csv, html, markdown, sarif, ai, badge, xcode, threshold, silent.
- OXC-based JS/TS tokenization — JavaScript/TypeScript/JSX/TSX tokenization now uses the OXC parser instead of PrismJS for better accuracy and speed.
- Parallel detection —
--workers Ncontrols thread count. Detection runs in parallel across format groups. - CLI alignment — new
--absolute,--ignore-case,--formats-exts,--formats-namesflags; fixed--threshold; improved--max-size. - Side-by-side blame — console-full reporter shows side-by-side blame comparison with
--blame. - In-process git blame — uses gitoxide instead of shelling out to
git blameper file; 27.5x faster blame on typical projects. - Dual npm package —
jscpd@5andcpdboth install the same Rust binary via platform-specific optional dependencies.
Breaking Changes from v4
- No Node.js API —
import { jscpd } from 'jscpd'is not available in v5. Use the CLI, Rust crate, orjscpd-serverREST API instead. - No
--store leveldb— external store backends are not supported in v5 (detection is fast enough without caching). - Reporter name change — v4's
fullreporter is nowconsole-fullin v5. - Output filenames — HTML reporter outputs
jscpd-report.htmlat the output directory root. - Token counts — may differ by 1-2% due to the Rust tokenizer using OXC for JS/TS.
- Format count — 223 formats (vs. v4's 224).
v5.0.3
- Full Rust CLI feature parity with TypeScript jscpd
- Cross-platform binary distribution via npm platform packages
- CLI short-form aliases matching TypeScript jscpd conventions
- Time reporter for execution timing
- ReportContext struct for extensible reporter signatures
v5.0.2
- Fixed Vue SFC tokenization (each block dispatched to its own sub-format)
- Fixed entire-file duplicates silently dropped by RabinKarp store flush logic
- Fixed ReDoS hang on Lisp/Elisp files
- Fixed crash on malformed package.json when reading config
v5.0.1
- Initial Rust workspace with cpd-core, cpd-tokenizer, cpd-finder, cpd-reporter, and jscpd crates
- Cross-format detection for Vue SFC, Svelte, Astro, and Markdown
- Shebang detection for extensionless scripts
v5.0.0
- First stable Rust release — replaces the TypeScript CLI with a native binary
- Reporter trait signature changed to use ReportContext instead of Statistics directly
v4.2.5
- JSON reporter token count fix, gitignore parent-directory walk, Commander v15, Vitest 4.1.0
v4.2.3
- fix(finder): resolve relative ignore patterns against scan dirs (#611)
- Dependency bumps across all packages
v4.2.2
- fix(tokenizer): resolve quadratic bash tokenization hang
v4.2.1
- fix(tokenizer): fix tokenization issue for cross-format detection
v4.2.0
New Features
- Custom tokenizer backend —
@jscpd/tokenizernow uses a self-contained reprism-based engine. ~11.5% faster tokenization on real projects (avg 1126 ms → 997 ms on a 548-file, 223-format scan). - Cross-format detection — Vue SFC (
.vue), Svelte (.svelte), Astro (.astro), and Markdown files are tokenized per-block/per-section, enabling duplicate detection between embedded blocks and standalone source files. - 223 supported formats — Apex, CFML/ColdFusion, GDScript, Svelte, Astro, and 70+ additional languages (up from 152). Run
jscpd --listto see the full list. - Shebang detection — extensionless executable scripts are auto-detected via their
#!shebang line. --store-path— specify a custom directory for the LevelDB token cache, eliminating collisions when multiple jscpd processes run concurrently.--skipComments— shorthand for--mode weak. Strips comments before tokenization.--formats-names— map specific filenames (e.g.Makefile,Dockerfile) to a detection format.
Bug Fixes
- Entire-file duplicates silently dropped (#728) — fixed RabinKarp end-of-file flush bug in
@jscpd/core. - ReDoS hang on Lisp/Elisp files (#737) — replaced catastrophic backtracking with a linear regex in
@jscpd/tokenizer. - Process crash on malformed
package.json(#739) — now emits a warning and continues. - Vue SFC cross-file detection broken — blocks now use resolved sub-format namespace.
- Vue SFC incorrect column numbers — fixed in
@jscpd/tokenizer. - 50 dependency security vulnerabilities remediated.
v4.1.1
- Update hash function, improve performance and keep browser support.
v4.1.0
- AI reporter (
--reporters ai) — compact, token-efficient output for LLMs. --noTipsflag — suppress usage-tip messages after detection.- Execution timer — timing summary shown after detection completes.
- Tokenizer speed — lazy Prism grammar loading, O(1) extension lookup, native MD5 hashing.
- New languages: Apex and CFML (ColdFusion).
- Test coverage raised to 98%+.
Earlier releases (v1.x – v4.0.x)
See the root CHANGELOG for the full history of jscpd versions 1.0.0 through 4.0.9, covering the tool's origins, the TypeScript rewrite, LevelDB store, pluggable reporters, monorepo extraction, and all the improvements made from 2018 through 2024.