Find duplicated logic in Rust, C and C++ — and keep finding the same duplication across scans.
codehelion reads sources directly: no build, no compilation database, no network. It detects identical, renamed and gapped copies, judges each one on several measures it reports side by side, and names every finding by a content-derived identifier that survives unrelated edits — so duplication you have already ruled on stays ruled on, and a scan months later can be measured against the one before it.
Everything runs on the machine you start it on. Sources and results are never sent anywhere, the tool has no network dependency, and it does not execute the code it reads unless you pass a flag that permits a specific class of execution.
codehelion is pre-1.0, and its parts are not all at the same stage.
Settled — scanning a tree in Fast or Structural mode, the text report,
replaying a recorded run with report and explain, the JSON export, and
reading a compiled artifact with artifact analyze. These have measured accuracy
and have been used on real projects; a breaking change to one gets a release
note.
Still finding its shape — Semantic mode, baselines, SARIF, seam tracking and
guard, artifact compare, calibration, history, and the configuration keys
that tune suppression. Each is documented and tested, and none has had the real
use that would make it worth a promise, so each can change between releases. The
page for every one of them says so at the top.
The on-disk database layout is not a stable surface either way; a scan recreates it.
Structural mode, run against codehelion's own tree, showing the first two groups:
codehelion scan · structural mode · ~/src/codehelion
#1 0.56 type-1 ×2 109 tokens b92c1297
├─ ◆ corpus/synthetic/rust/seed.rs:30-49 values_equal
└─ corpus/synthetic/rust/type1.rs:35-54 values_equal
#2 0.53 type-1 run ×2 101 tokens 5d7e5cd2
├─ ◆ crates/codehelion-cli/src/scan/structural.rs:177-183 run_with
└─ crates/codehelion-cli/src/scan.rs:62-68 run
... and 1184 more groups (--limit 0 lists every one)
seams: frontend-c-cpp 12 asymmetric changes, 7 breaches (last 6e014d86), 394 findings
readme-en-ja 1 asymmetric change, 1 breach (last 634aa5c9)
artifact-fixture-scripts 3 asymmetric changes, 1 breach (last 6f5d63c3)
since seam run 4: frontend-c-cpp -1,159 findings
1,538 groups (type-1 78, type-2 198, type-3 1262) · 352 suppressed · sorted by priority
supplemental: 492 siblings (--show-siblings; 60 dropped by search ceilings), 1,000 near misses (--show-near-misses; 5,633 dropped by the retention cap)
553 files, 199,546 lines, 1,042,197 tokens · run 9 (0 file(s) changed; replay: codehelion report --run 9)
◆ the occurrence a group is measured against · "run" a repeated stretch of statements, not a whole unit · ×N the number of occurrences
open one: codehelion explain b92c1297 · list every group: --limit 0
Every field, and what -v and -vv add:
Reading a report.
Sources are lexed and normalized, indexed by content, paired into candidates, verified by alignment, and grouped around a canonical member. The run is recorded into a local SQLite database, and the text, JSON and SARIF reports are exports of that record. Every resource ceiling that fires is counted in the report, so a run that could not finish the search says what it left unexamined.
- Build-free scanning — an error-tolerant lexer reads Rust, C and C++
sources directly, so a mixed-language tree is scanned once, on one basis. No
compiler, build system or
compile_commands.jsonis required. - Stable finding IDs — findings are named by content fingerprints, not line numbers. The same input always produces the same identifiers and the same group order, which is what makes suppressions and baselines hold across refactors.
- Evidence, not a single score — a gapped clone reports lexical, structural, control-flow, type and API similarity separately, and clone confidence, maintenance risk and refactoring difficulty side by side. A dimension the mode cannot measure is reported as absent rather than guessed.
- Visible limits — every resource ceiling that fires (file size, parse timeout, candidate budget) is counted in the report.
- Local by construction — the ban on network access and on executing the
scanned tree is enforced by lints and dependency policy, not by convention:
clippy.tomldisallows process spawning and sockets in the scan path, andcargo-denyrefuses the common HTTP stacks outright.
Every release attaches a
prebuilt binary, so nothing has to be compiled to try it. The archive holds one
self-contained executable named codehelion; SQLite is bundled.
| platform | archive |
|---|---|
| Linux x86-64 | codehelion-<version>-linux-x86_64.tar.gz |
| Linux ARM64 | codehelion-<version>-linux-aarch64.tar.gz |
| macOS Apple silicon | codehelion-<version>-macos-aarch64.tar.gz |
| Windows x86-64 | codehelion-<version>-windows-x86_64.zip |
SHA256SUMS is attached beside them. With a Rust toolchain, cargo install
builds the same binary from source instead:
cargo install codehelionThat route requires Rust 1.98 or newer, the optional Rust semantic helper included.
codehelion scan --mode structural # read the tree, report the duplication
codehelion explain b92c1297 # open one group
codehelion report --format json --output report.jsonSemantic mode additionally needs a helper per language. Prebuilt helper archives
(codehelion-helpers-<version>-...) are attached for Linux x86-64, macOS Apple
silicon and Windows x86-64; elsewhere, cargo install codehelion-backend-rust
and codehelion-backend-clang build them. codehelion doctor reports what this
machine has. Full setup: Getting started.
scan --fail-on-findings against a baseline exits 3 when duplication arrives
that the baseline does not already carry — a gate on what a change added, not on
a percentage that raising the number would answer. guard --deny-asymmetric
exits 3 when a change touched part of a seam and not the rest. --format sarif uploads into a code-scanning view.
Continuous integration has all three.
Start here: Introduction, Getting started, Analysis modes.
Reading the output: Reading a report, Clone types, Grouping, Stable identifiers, Glossary.
Using it on a project: The refactoring loop, Baselines, Suppression, Configuration, Seam tracking, Continuous integration, The command line.
Artifacts: Artifact analysis, Calibration.
Before you rely on it: Limitations, Accuracy, Local execution and trust, Architecture.
A finding measures maintainability, not size: it names code a reader has to keep
in step, not bytes a compiler emits. Optimisers fold identical code that is still
duplicated in the source, and the compressed size of an artifact moves far less
than its uncompressed size does.
codehelion artifact analyze measures that side
separately. codehelion is not a mirror-consistency checker either: it reports the
duplication it finds without claiming to have found every copy. The whole list is
in Limitations.
What is measured, over eight labelled snapshots of real projects: nothing false reaches the first ten findings (p@10 1.0000, MAP 0.9290) under the default priority ordering. Read end to end instead, the same verdicts give 0.5920 — the tail is close to half noise, which is why the report is ordered rather than merely listed. Both figures, their corpora and how to reproduce them are in Accuracy.
make format # auto-fix: clippy --fix + cargo fmt
make check # format-check + lint + boundary checks + test + doc
make eval # detection accuracy over the corporamake help lists the rest. Guardrails: rustfmt with a pinned config, clippy
pedantic + nursery with warnings as errors, unsafe forbidden, cargo-deny
over advisories, bans and licences, and two boundary checks that fail if the
clone engine gains a dependency on the artifact reader or a compiler API reaches
the CLI. Tests are written alongside the code they cover.
See CONTRIBUTING.md. To report a security issue, follow SECURITY.md rather than opening a public issue.
Licensed under the Apache License, Version 2.0.