npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

duplicalis

v2.0.4

Published

CLI to detect duplicate or near-duplicate React components (code + styles).

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 scan

Or install it:

npm install -D duplicalis
npx duplicalis scan

First 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

📚 Usage Examples

1. Default Scan

npx duplicalis scan

2. 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 scan

4. Save a JSON Report

npx duplicalis scan --no-progress --out report.json

Reports 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-config

Saving 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.