A powerful CLI tool for analyzing and cleaning JavaScript/TypeScript codebases.
Surgeon performs static analysis to detect code health issues like dead files, unused exports, circular dependencies, oversized modules, complex functions, and environment variable mismatches.
- Dead Code Detection — Find files and exports that are never used
- Dependency Analysis — Map import relationships and detect circular dependencies
- Size Analysis — Identify oversized files and functions
- Complexity Analysis — Detect functions with high cyclomatic/cognitive complexity
- Env Variable Audit — Cross-check
.envfiles against actual usage - Multiple Output Formats — Terminal, Markdown, JSON, and HTML reports
- Watch Mode — Continuous analysis as files change
- Git Integration — Analyze only changed files
- Auto-Fix — Automatically remove dead code
- Baseline Mode — Track issues over time, fail only on new issues
- Plugin System — Extend with custom analyzers and reporters
- CI/CD Ready — GitHub Actions, pre-commit hooks, and more
npm install -g surgeon-cliOr use directly with npx:
npx surgeon-cli scan# Run all analyzers
surgeon scan
# Find dead code
surgeon deadcode
# Check for circular dependencies
surgeon deps
# Audit environment variables
surgeon env check
# Watch for changes
surgeon watch
# Interactive mode
surgeon interactive
# Generate an HTML report
surgeon report html --runRun all analyzers and report findings.
surgeon scan [options]
Options:
--cwd <path> Working directory (default: current directory)
--config <path> Path to config file
--json Output as JSON
--quiet Suppress progress output
--parallel Run analyzers in parallel (faster)
--cache Cache results for faster subsequent runs
--fail-on <level> Exit 1 if findings at level or above (error|warning|info)Watch for file changes and run analysis continuously.
surgeon watch [options]
Options:
--cwd <path> Working directory
--config <path> Path to config file
--analyzers <list> Comma-separated analyzers (default: deadcode,deps,size)
--debounce <ms> Debounce time in milliseconds (default: 500)
--clear Clear screen between runsAnalyze only files that have changed (git integration).
surgeon changed [options]
Options:
--cwd <path> Working directory
--base <ref> Base branch/commit to compare against (default: main)
--uncommitted Only analyze uncommitted changes
--json Output as JSON
--analyzers <list> Comma-separated analyzersFind unused files and exports.
surgeon deadcode [options]
Options:
--cwd <path> Working directory
--json Output as JSON
--exports-only Only check exports, skip file analysis
--files-only Only check files, skip export analysisAnalyze dependency graph and detect circular imports.
surgeon deps [options]
Options:
--cwd <path> Working directory
--json Output as JSON
--cycles-only Only report circular dependenciesAudit environment variable usage.
surgeon env check [options]
Options:
--cwd <path> Working directory
--env-file <path> Env file to check (can be repeated)
--json Output as JSON
--strict Treat unused variables as errorsAutomatically fix issues (remove dead code).
surgeon fix [options]
Options:
--cwd <path> Working directory
--dry-run Show what would be fixed without making changes
--backup Create backups before modifying files
--types <list> Fix types: dead-file, unused-export (default: both)
--yes Skip confirmation promptManage analysis baselines for tracking new issues.
# Save current state as baseline
surgeon baseline save
# Check for new issues compared to baseline
surgeon baseline check [--fail-on-new]
# Show detailed diff from baseline
surgeon baseline diff
# Remove baseline
surgeon baseline clearGenerate reports from analysis results.
surgeon report <format> [options]
Arguments:
format Output format (markdown|json|html)
Options:
--cwd <path> Working directory
--output <path> Output file path
--run Run fresh scan before reportingInteractive mode for reviewing and fixing issues.
surgeon interactive
# or
surgeon iFeatures:
- Menu-driven interface
- Select specific analyzers to run
- Review issues and selectively fix them
- Configure thresholds on the fly
Generate CI/CD configuration files.
# Generate GitHub Actions workflow
surgeon ci github-actions [--fail-on <level>]
# Generate pre-commit configuration
surgeon ci pre-commit
# Generate Husky pre-commit hook
surgeon ci husky
# Show lint-staged configuration
surgeon ci lint-stagedManage surgeon plugins.
# Create a new plugin from template
surgeon plugin create <name>
# List configured plugins
surgeon plugin listCreate a starter configuration file.
surgeon init [options]
Options:
--cwd <path> Working directory
--format <type> Config format (js|json)
--force Overwrite existing configCreate a surgeon.config.js file in your project root:
export default {
include: ['**/*.{ts,tsx,js,jsx}'],
exclude: ['**/node_modules/**', '**/dist/**'],
maxFileLines: 500,
maxFunctionLines: 50,
analyzers: {
deadcode: { enabled: true },
deps: { enabled: true },
env: { enabled: true, files: ['.env'] },
size: { enabled: true },
complexity: {
enabled: true,
maxCyclomaticComplexity: 10,
maxCognitiveComplexity: 15,
},
},
reporters: ['terminal'],
plugins: [],
};| Option | Type | Default | Description |
|---|---|---|---|
include |
string[] |
['**/*.{ts,tsx,js,jsx}'] |
Glob patterns for files to include |
exclude |
string[] |
['**/node_modules/**', ...] |
Glob patterns for files to exclude |
maxFileLines |
number |
500 |
Warn if file exceeds this many lines |
maxFunctionLines |
number |
50 |
Warn if function exceeds this many lines |
outputDir |
string |
'.surgeon' |
Directory for report output |
reporters |
string[] |
['terminal'] |
Enabled reporters |
plugins |
string[] |
[] |
Plugin names or paths to load |
analyzers: {
deadcode: {
enabled: true,
entryPoints: ['src/index.ts'], // Additional entry points
},
deps: {
enabled: true,
maxDepth: 10, // Max dependency depth
},
env: {
enabled: true,
files: ['.env', '.env.local'],
},
size: {
enabled: true,
maxFileLines: 300, // Override global setting
maxFunctionLines: 30,
},
complexity: {
enabled: true,
maxCyclomaticComplexity: 10,
maxCognitiveComplexity: 15,
},
}Surgeon supports inline comments to suppress specific warnings.
// surgeon-ignore-next-line
export function intentionallyUnused() {}
// surgeon-ignore-next-line deadcode
export const API_CONSTANT = 'value';// surgeon-ignore-file
// This entire file is excluded from all analysis
export function willNotBeFlagged() {}| Comment | Effect |
|---|---|
// surgeon-ignore-next-line |
Ignore all analyzers for next line |
// surgeon-ignore-next-line deadcode |
Ignore only dead code analysis |
// surgeon-ignore-next-line size |
Ignore only size analysis |
// surgeon-ignore-next-line deps |
Ignore only dependency analysis |
// surgeon-ignore-next-line complexity |
Ignore only complexity analysis |
// surgeon-ignore-file |
Ignore all analyzers for entire file |
// surgeon-ignore-file deadcode |
Ignore dead code for entire file |
surgeon ci github-actionsCreates .github/workflows/surgeon.yml that:
- Runs on push and pull requests
- Fails if issues exceed threshold
- Uploads HTML report as artifact
- Comments on PRs with issues
surgeon ci pre-commitCreates .pre-commit-config.yaml with hooks for:
- Analyzing changed files on commit
- Baseline check on push
surgeon ci huskyCreates .husky/pre-commit hook that runs surgeon on changed files.
Add plugins to your configuration:
export default {
plugins: [
'./my-local-plugin.js',
'surgeon-plugin-react',
],
};surgeon plugin create my-analyzerThis creates a template with:
- Custom analyzer example
- Custom reporter example
- Setup hook
Example plugin structure:
export default {
name: 'my-plugin',
version: '1.0.0',
analyzers: [{
name: 'my-analyzer',
description: 'My custom analyzer',
async analyze(context) {
// Your analysis logic
return { analyzer: 'my-analyzer', findings: [], stats: {}, duration: 0 };
},
}],
reporters: [{
name: 'my-reporter',
format: 'custom',
async generate(results, config) {
// Your reporting logic
},
}],
};Run analyzers concurrently for faster results:
surgeon scan --parallelCache results based on file content hashes:
surgeon scan --cacheSubsequent runs with unchanged files will use cached results.
| Code | Meaning |
|---|---|
0 |
Success, no issues (or below threshold) |
1 |
Issues found at or above threshold |
2 |
Configuration error |
3 |
Runtime error |
git clone https://github.com/anthropics/surgeon-cli.git
cd surgeon-cli
npm installnpm run dev # Run CLI in development mode
npm run build # Build TypeScript
npm run test # Run tests
npm run test:watch # Run tests in watch mode
npm run lint # Run ESLint
npm run format # Run Prettier
npm run typecheck # Run TypeScript type checkingsrc/
├── cli/ # CLI commands and entry point
│ ├── commands/ # Individual command implementations
│ └── index.ts # CLI entry point
├── analyzers/ # Code analyzers
│ ├── deadcode.analyzer.ts
│ ├── deps.analyzer.ts
│ ├── env.analyzer.ts
│ ├── size.analyzer.ts
│ └── complexity.analyzer.ts
├── reporters/ # Output reporters
│ ├── terminal.reporter.ts
│ ├── markdown.reporter.ts
│ ├── json.reporter.ts
│ └── html.reporter.ts
├── core/ # Core infrastructure
│ ├── config.ts # Configuration loading
│ ├── context.ts # Analysis context
│ ├── watcher.ts # File watching
│ ├── baseline.ts # Baseline management
│ ├── cache.ts # Result caching
│ ├── fixer.ts # Auto-fix logic
│ └── plugins.ts # Plugin system
├── types/ # TypeScript type definitions
└── utils/ # Utility functions
MIT