Blazing-fast dead code elimination for JavaScript and TypeScript
Sweepr is a powerful static analysis tool that identifies unused code, dependencies, and exports in your JavaScript/TypeScript projects. Built with Rust and leveraging the oxc parser, it provides lightning-fast code analysis with parallel processing.
Sweepr is a proof-of-concept (PoC) project inspired by knip, the excellent dead code elimination tool for JavaScript/TypeScript. The goal of this project is to explore the performance benefits of implementing static analysis using Rust and the oxc parser suite.
While knip provides comprehensive analysis and production-ready features, Sweepr focuses on:
- Performance optimization through Rust's zero-cost abstractions and memory safety
- Parallel processing using Rayon for multi-core utilization
- Fast parsing with oxc's next-generation JavaScript/TypeScript parser
- Learning opportunity to understand the trade-offs between Node.js and Rust implementations
This project serves as an experiment to measure how a systems programming language can improve the tooling ecosystem for JavaScript/TypeScript development.
- 🔍 Dead Code Detection - Find unused exports, functions, and variables
- 📦 Dependency Analysis - Identify unused npm packages
- 🗂️ File Reachability - Detect files that aren't imported by your entry points
- ⚡ Blazing Fast - Parallel parsing and analysis powered by Rust
- 🎯 Framework Agnostic - Works with React, Vue, Angular, Node.js, and more
- 📊 Multiple Output Formats - Human-readable CLI output or JSON for CI/CD
# Install Rust toolchain if you haven't already
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Clone and build
git clone https://github.com/user/sweepr.git
cd sweepr
cargo build --release
# The binary will be at target/release/sweeprcargo install --path .# Analyze your project
sweepr check
# Analyze with custom entry points
sweepr check --entry src/main.ts --entry src/app.ts
# Output results in JSON format
sweepr check --jsonThe check command scans your project and reports unused code without making any changes.
# Basic check with default entry point
sweepr check
# Specify custom entry points
sweepr check --entry src/index.ts
# Multiple entry points
sweepr check -e src/main.ts -e src/app.ts
# JSON output for CI/CD integration
sweepr check --json > analysis-results.jsonNote: The fix functionality is not yet implemented, but planned for future releases.
# Safe fixes only (comment out unused code)
sweepr fix
# Allow dangerous operations (delete files)
sweepr fix --unsafeCreate a sweepr.config.json file in your project root:
{
"entry": ["src/index.ts", "src/app.ts"],
"ignore": [
"**/*.test.ts",
"**/*.spec.ts",
"**/node_modules/**",
"src/legacy/**"
],
"rules": {
"unused_deps": true,
"unused_exports": true,
"unused_files": true
},
"framework": "react"
}-
entry(array, required) - Entry point files for your application- Default:
["src/index.ts"] - Examples:
["src/main.ts"],["src/client.tsx", "src/server.ts"]
- Default:
-
ignore(array, optional) - Glob patterns for files to ignore- Default:
["**/*.test.ts", "**/*.test.js", "**/*.spec.ts", "**/*.spec.js", "**/node_modules/**"] - Supports glob patterns like
**/*.test.tsorsrc/legacy/**
- Default:
-
rules(object, optional) - Enable/disable specific rulesunused_deps(boolean, default:true) - Check for unused npm dependenciesunused_exports(boolean, default:true) - Check for unused exportsunused_files(boolean, default:true) - Check for unreachable files
-
framework(string, optional) - Framework-specific optimizations- Supported:
react,vue,angular,svelte,node - Improves detection accuracy with framework-specific patterns
- Supported:
Scans your package.json and identifies packages that are never imported:
📦 Unused Dependencies (3)
• lodash (4.17.21)
• moment (2.29.4)
• axios (1.6.0)
Finds exported functions, classes, and variables that are never imported:
📄 Unused Exports in src/utils/helpers.ts (2)
• formatDateTime (line 15)
• parseQueryString (line 23)
Identifies files that aren't reachable from your entry points:
🗑️ Unreachable Files (5)
• src/legacy/auth.ts
• src/components/old/Button.tsx
• src/utils/deprecated.ts
# Analyze a React app
sweepr check --entry src/main.tsx
# Output:
🚀 Scanning workspace...
📄 Found 127 files
🎯 Entry points: 1
🔬 Analyzing code...
✓ Parsed 127 files
✓ Built analysis graphs
✓ Loaded 45 dependencies
📊 Analysis Results
📦 Unused Dependencies: 3
📄 Unused Exports: 12
🗑️ Unreachable Files: 2
⏱️ Completed in 234.56ms# Analyze a Node.js API
sweepr check --entry src/server.ts --entry src/cli.ts
# Or create a config file
cat > sweepr.config.json << EOF
{
"entry": ["src/server.ts", "src/cli.ts"],
"ignore": ["**/*.test.ts", "scripts/**"],
"rules": {
"unused_deps": true,
"unused_exports": true,
"unused_files": false
}
}
EOF
sweepr check# In your CI pipeline
sweepr check --json | jq '.unused_dependencies | length'
# Exit with error if too many unused deps
if [ $(sweepr check --json | jq '.unused_dependencies | length') -gt 5 ]; then
echo "Too many unused dependencies!"
exit 1
fiSweepr uses sophisticated static analysis to understand your code:
- File Discovery - Scans your project for JS/TS files
- Parallel Parsing - Uses multiple CPU cores to parse files simultaneously
- AST Analysis - Builds abstract syntax trees to understand code structure
- Graph Building - Creates dependency graphs for files, symbols, and packages
- Reachability Analysis - Traces code from entry points to find what's used
- Reporting - Generates actionable insights about unused code
Sweepr is optimized for speed:
- Parallel parsing using Rayon
- Efficient AST with oxc allocator
- Incremental analysis support (planned)
Benchmarks on a typical mid-size project (500 files):
| Tool | Time |
|---|---|
| Sweepr | ~200ms |
| ESLint | ~2s |
| TypeScript compiler | ~5s |
-
fixcommand implementation - Framework-specific rules (React hooks, Vue composables)
- Incremental analysis mode
- VS Code extension
- Web UI for analysis results
- Support for more file types (JSX, TSX, JSON imports)
- Configuration file TypeScript support
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
# Run tests
cargo test
# Run with logging
RUST_LOG=debug cargo run -- check
# Format code
cargo fmt
# Run linter
cargo clippyMIT License - see LICENSE file for details
Built with amazing open-source tools:
- knip - Inspiration and test fixtures
- oxc - JavaScript/TypeScript tooling
- clap - Command line argument parser
- rayon - Parallelism library
- serde - Serialization framework
Made with ❤️ by the Sweepr contributors