duplicalis
v2.0.4
Published
CLI to detect duplicate or near-duplicate React components (code + styles).
Maintainers
Readme
Duplicalis helps you find duplicate or near-duplicate React components in your codebase. It analyzes component logic, structure, and styles to identify components that can be refactored or merged.
It uses AI embeddings plus AST-based analysis, so it can catch near-duplicates even when variable names or formatting differ.
🧭 Architecture
+----------------------+
| CLI / Config |
+----------+-----------+
|
v
+------------------+ +-------+--------+ +----------------------+
| React Source |<->| Analysis Core |<->| Analysis Cache |
| files | | parse + style | +----------------------+
+------------------+ | + representations|
+-------+--------+
|
v
+-------+--------+ +----------------------+
| Embedding Layer |<->| Embedding Cache |
+-------+--------+ +----------------------+
|
v
+-------+--------+
| Embedding |
| Backend |
| local / remote |
| / mock |
+-------+--------+
|
v
+-------+--------+
| Matching + |
| Labels |
+-------+--------+
|
v
+----------------+
| Console / JSON |
| reports |
+----------------+Developer-focused architecture notes live in ARCHITECTURE.md.
🚀 Quick Start
Run directly:
npx duplicalis scanOr install it:
npm install -D duplicalis
npx duplicalis scanFirst run downloads the local model automatically.
🏷️ Duplication Types
duplicalis categorizes matches to help you decide how to fix them:
| Label | Description |
| :---------------------- | :------------------------------------------------------------------------------------------- |
| #prop-parameterizable | Components are identical except for values (e.g., text, colors). Merge them by adding props. |
| #copy-paste-variant | Very high similarity. Likely a copy-paste with minor edits. |
| #logic-duplicate | The internal logic (hooks, handlers) is the same, even if the UI looks different. |
| #style-duplicate | The styles are nearly identical, even if the component code differs. |
| #wrapper-duplicate | Both components are thin wrappers around the same base component. |
| #forked-clone | High similarity but with uneven changes. Suggests one should be the "canonical" version. |
⚙️ Common Options
| Flag | Description | Default |
| :--------------------- | :------------------------------------------------------------- | :--------------------------- |
| --threshold <number> | Minimum similarity to report a pair (0.0 to 1.0). | 0.85 |
| --limit <number> | Max number of matches to show per component. | All |
| --exclude <globs> | Patterns to exclude (e.g., **/*.test.tsx). | node_modules, dist, etc. |
| --out <path> | Save the report to a JSON file. | None |
| --compare <globs> | Only report pairs involving these files (e.g., changed files). | None |
| --relative-paths | Show relative paths in output. | false |
| --lang <code> | Output language (en, ru, es, fr, de, zh). | en |
📊 Model Snapshot
This is the current bundled-suite snapshot with the live 45/30/25 benchmark score. The table below
is intentionally simplified. Score is a benchmark fit score where higher is better. For the
full methodology, metrics, tradeoffs, and detailed results, see BENCHMARK.md.
Snapshot date: March 28, 2026
| Model | Score | | :--------------------- | ----: | | all-mpnet-base-v2 | 98.9 | | Gemini Embedding 001 | 98.8 | | Multilingual-E5-Large | 98.7 | | OpenAI 3 small | 98.6 | | BGE-M3 | 96.3 | | OpenAI 3 large | 94.9 | | Local all-MiniLM-L6-v2 | 93.6 | | Qwen3 Embedding 8B | 92.0 |
📚 More Docs
- Full configuration and flag reference: CONFIGURATION.md
- Release flow: RELEASE.md
📚 Usage Examples
1. Default Scan
npx duplicalis scan2. Compare Changed Files
npx duplicalis scan . --compare "src/features/**/*.{ts,tsx}"3. Use a Remote Model
You can also put these variables in a .env file in the directory where you run the command.
Variables already set in your shell take priority over .env.
export MODEL=remote
export API_URL=https://openrouter.ai/api/v1/embeddings
export API_KEY=sk-or-...
export API_MODEL=openai/text-embedding-3-small
npx duplicalis scan4. Save a JSON Report
npx duplicalis scan --no-progress --out report.jsonReports preserve component snippets and source locations, including files with leading comments or Unicode text.
5. Save Your Defaults
npx duplicalis scan --threshold 0.9 --exclude "**/*.test.tsx" --save-configSaving defaults does not copy API keys from the environment, CLI, or another config file.
An API key already in the destination config is preserved. Prefer API_KEY for credentials.
Built for cleaner, more maintainable React codebases.
