Skip to content

ojuschugh1/ghostdep

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ghostdep 👻

A fast, cross-language phantom dependency detector. Finds packages you import but forgot to declare, and packages you declared but never use.

Built in Rust. Zero runtime dependencies. Single binary.

Why?

Ever had a build break in CI because someone imported a package that was only available transitively? Or shipped a bloated package.json full of deps nobody uses anymore?

ghostdep catches both:

  • Phantom dependencies — imported in code but missing from your manifest
  • Unused dependencies — declared in your manifest but never imported

Supported Languages

Language Manifest Parser Status
Go go.mod tree-sitter stable
JavaScript/TypeScript package.json OXC stable
Python requirements.txt, pyproject.toml (PEP 621 + Poetry + uv) tree-sitter stable
Rust Cargo.toml tree-sitter stable
Java pom.xml, build.gradle tree-sitter + regex beta

Note on Java: Java import-to-artifact mapping is inherently heuristic — there's no standard 1:1 mapping between import paths and Maven artifact IDs. ghostdep ships with a table of ~150 common libraries and falls back to groupId matching against your pom.xml/build.gradle. It works well for popular libraries but may miss niche ones. PRs to expand the mapping table are very welcome.

Quick Start

# install from source (crates.io publish coming soon)
cargo install --path .

# or grab a binary from releases
curl -fsSL https://raw.githubusercontent.com/ojuschugh1/ghostdep/main/install.sh | sh

# scan your project
ghostdep

# scan a specific directory
ghostdep -p /path/to/project

# json output for CI
ghostdep -f json

# sarif output for github code scanning
ghostdep -f sarif

Usage

ghostdep [OPTIONS] [COMMAND]

Commands:
  scan   Scan for phantom and unused dependencies (default)
  init   Generate a default .ghostdep.yaml config
  fix    Generate fix commands for findings

Options:
  -p, --path <PATH>              Project root [default: .]
  -f, --format <FORMAT>          Output format: text, json, sarif
      --min-confidence <LEVEL>   Filter by confidence: low, medium, high
  -i, --ignore <PATTERN>         Ignore deps matching glob pattern
  -l, --language <LANG>          Restrict to a specific language
      --dev                      Include dev dependencies
      --threads <N>              Number of scanner threads
      --cache                    Enable incremental scan cache
  -v, --verbose                  Print progress info
  -q, --quiet                    Suppress output (exit code only)
  -h, --help                     Print help
  -V, --version                  Print version

Example Output

$ ghostdep -p my-project

[phantom] axios at src/api.js:3 (confidence: high)
[phantom] pandas at app.py:7 (confidence: high)
[unused] lodash at package.json (confidence: high)
[unused] numpy at requirements.txt (confidence: high)

Found 2 phantom and 2 unused dependencies (42 files scanned in 15ms)

Auto-Fix

ghostdep generates the exact package manager commands to fix your deps:

# preview what would be run
ghostdep fix --dry-run

Output:

npm install axios
npm uninstall lodash
pip install pandas
pip uninstall numpy

You can also let ghostdep run the commands directly (it'll ask for confirmation first):

ghostdep fix --apply

This works for npm/yarn, pip, cargo, and go. For Maven and Gradle, it prints the snippets you need to add/remove manually since those don't have clean CLI commands for it.

Configuration

Create a .ghostdep.yaml in your project root (or run ghostdep init):

ignore_deps:
  - "internal-*"
  - "my-shared-lib"
ignore_paths:
  - "scripts/**"
  - "generated/**"
include_dev: true
min_confidence: low
format: text
cache: false

CLI flags always override the config file. Ignore lists are additive across both.

Monorepo Support

ghostdep automatically detects monorepos with multiple manifests. Cross-project imports between sibling packages won't be flagged as phantoms.

Confidence Scoring

Not all imports are created equal:

Confidence What it means
high Static import at top level (import x, use x, require("x"))
medium Conditional import (try/except, dynamic import("x") with string)
low Dynamic import with variable (require(expr), importlib.import_module(var))

Filter by confidence with --min-confidence:

# only show high-confidence findings
ghostdep --min-confidence high

CI Integration

ghostdep exits with code 1 when findings are present, making it easy to use in CI:

# GitHub Actions
- name: Check dependencies
  run: ghostdep -f sarif > results.sarif

- name: Upload SARIF
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: results.sarif

WASM Plugins (Experimental)

ghostdep has a WASM plugin host that can load .wasm files from plugins/ in your project root or ~/.ghostdep/plugins/. This lets you add support for languages ghostdep doesn't cover yet.

The plugin API is functional but not yet documented — if you're interested in writing a plugin, look at src/plugin/wasm_host.rs for the expected exports. Proper docs and an example plugin are on the roadmap.

Building from Source

git clone https://github.com/ojuschugh1/ghostdep
cd ghostdep
cargo build --release

Run the tests:

cargo test

Roadmap

Here's what's shipped and what's coming:

v1 (current) — shipped:

  • Scanning for Go, JS/TS, Python, Rust, Java
  • AST-based import extraction with confidence scoring
  • Text, JSON, SARIF output
  • Fix command generation (dry-run and apply)
  • Monorepo support
  • Incremental caching
  • WASM plugin host (experimental, undocumented API)
  • GitHub Actions release workflow

v1.x — next up:

  • WASM plugin API documentation + example plugin
  • Homebrew tap
  • crates.io publish
  • Better Java import-to-artifact mapping
  • --fix for Maven/Gradle (direct manifest editing)

v2 — planned:

  • Transitive dependency analysis
  • AI hallucination detection (flag phantom deps that don't exist in any registry)
  • LSP integration (real-time warnings in your editor)
  • Lockfile reconciliation

Contributing

We're actively looking for contributors! Whether it's adding support for a new language, improving detection accuracy, fixing bugs, or writing docs — all contributions are welcome.

Some ideas to get started:

  • Add support for new languages (Ruby, PHP, C#, Swift...)
  • Improve the Java import-to-artifact mapping
  • Write a WASM plugin for your favorite language
  • Write more property-based tests
  • Improve monorepo package name extraction
  • Document the WASM plugin API

Open an issue or submit a PR. No contribution is too small.

License

MIT — see LICENSE for details.


Made with ❤️ for the open source community.

About

Detect phantom and unused dependencies across multiple languages using a fast Rust-based CLI

Topics

Resources

License

Stars

Watchers

Forks

Packages