A Haskell tool for whole-program dead-code analysis using GHC's HIE files to detect unused code across module boundaries.
Weeder is a Haskell tool that performs whole-program dead-code analysis to identify code that is written but never reachable from other parts of a project. It solves the problem of leftover code accumulating over a project's lifetime by analyzing dependencies across module boundaries using GHC's HIE files. Unlike GHC's single-module warnings, Weeder provides a comprehensive view of unused code throughout the entire codebase.
Haskell developers and teams maintaining medium to large Haskell projects who want to keep their codebases clean and free of unused code. It's particularly useful for projects with many modules where cross-module dead code is hard to detect manually.
Developers choose Weeder because it fills a critical gap in Haskell's tooling by providing cross-module dead-code detection, which GHC doesn't offer. Its integration with existing build systems (Cabal, Stack, Nix) and configurable root detection make it practical for real-world projects with complex dependency structures.
A re-implementation of weeder using HIE files
Open-Awesome is built by the community, for the community. Submit a project, suggest an awesome list, or help improve the catalog on GitHub.
Uses GHC's HIE files to build a dependency graph across modules, solving GHC's limitation of single-module dead-code warnings as highlighted in the README.
Supports regular expressions and type-class instance settings in weeder.toml to fine-tune what's considered alive, reducing false positives with practical examples.
Works with Cabal, Stack, and Nix via simple configuration changes and companion projects, making it easy to integrate into existing workflows.
Offers optional analysis of unused types through the 'unused-types' setting, extending dead-code detection beyond functions and values.
Cannot parse Template Haskell splices, leading to false positives when code dependencies are introduced via TH, as admitted in the limitations section.
Fails to fully analyze uses of type family instances, marking them as implicit roots and potentially missing dead code in complex type-level code.
Requires manual setup of roots and tuning to handle issues like overloaded syntax, adding complexity compared to more automated tools.