Dangle is both an executable binary that can be run, and a library that can be used in Rust programs.
Installing the command-line executable
Assuming you have Rust/Cargo installed , run this command in a terminal:
cargo install dangle
It will make the dangle command available in your PATH if you've allowed the PATH to be modified when installing Rust . cargo uninstall dangle uninstalls.
Adding dangle library as a dependency
Run this command in a terminal, in your project's directory:
cargo add dangle
To add it manually, edit your project's Cargo.toml file and add to the [dependencies] section:
dangle = "0.4.0"
The dangle library will be automatically available globally.
Read the dangle library documentation .
Back to the crate overview .
Readme
dangle
A dead code detector for multi-language projects. Finds symbols that are defined but never
referenced elsewhere in your codebase.
Installation
cargo install dangle
Usage
Run dangle in a git repository to find dead code candidates:
dangle
Output format:
path/ to/ file. rs: 42 : 5 : fn unused_function is not referenced
path/ to/ file. py: 17 : 1 : class UnusedClass is not referenced
Options
- v, - - verbose - Show all definitions found
- h, - - help - Print help
How It Works
Dangle uses tree-sitter for accurate AST-based parsing. Unlike
regex-based approaches, it correctly ignores symbols that appear only in strings or comments.
The algorithm:
Discovers source files via git ls-files
Extracts definitions from non-test files using tree-sitter queries
Extracts all identifier references from all files (including tests)
Reports definitions that are referenced only once (the definition itself)
This means symbols used only in tests won't be flagged as dead code.
Supported Languages
More tree-sitter language support is planned for future releases.
Reference Detection
Dangle recognizes references in:
Direct identifier usage (function calls, type annotations, etc.)
Method calls (field identifiers)
String literals in Rust attributes (e.g., # [ serde ( default = " my_default_fn" ) ] )
Paths like " module::func_name" extract the leaf segment as the reference
Filters
Dangle automatically excludes:
main functions
test_* functions and Test* classes (Python)
# [ test ] functions (Rust)
# [ allow ( unused ) ] and # [ allow ( dead_code ) ] definitions (Rust)
__ * names (Python dunders, etc.)
Functions inside Rust trait impls (e.g., impl Drop , impl Iterator , etc.)
Private traits that are not implemented (public traits are assumed to be API)
Definitions marked with nodangle in a comment on the same line
License
MIT