Skip to content

Universal LSP server for dependency management — autocomplete, version hints, and diagnostics for Cargo.toml and package.json. Supports Zed, Neovim, Helix.

License

Notifications You must be signed in to change notification settings

bug-ops/deps-lsp

deps-lsp

Crates.io docs.rs codecov CI License: MIT MSRV unsafe forbidden

A universal Language Server Protocol (LSP) server for dependency management across multiple package ecosystems.

Features

  • Intelligent Autocomplete — Package names, versions, and feature flags
  • Version Hints — Inlay hints showing latest available versions
  • Loading Indicators — Visual feedback during registry fetches with LSP progress support
  • Lock File Support — Reads resolved versions from Cargo.lock, package-lock.json, poetry.lock, uv.lock, go.sum
  • Diagnostics — Warnings for outdated, unknown, or yanked dependencies
  • Hover Information — Package descriptions with resolved version from lock file
  • Code Actions — Quick fixes to update dependencies
  • High Performance — Parallel fetching with per-dependency timeouts, optimized caching

deps-lsp in action

Performance

deps-lsp is optimized for responsiveness:

Operation Latency Notes
Document open (50 deps) ~150ms Parallel registry fetching
Inlay hints <100ms Cached version lookups
Hover <50ms Pre-fetched metadata
Code actions <50ms No network calls

Tip

Lock file support provides instant resolved versions without network requests.

Supported Ecosystems

Ecosystem Manifest File Status
Rust/Cargo Cargo.toml ✅ Supported
npm package.json ✅ Supported
Python/PyPI pyproject.toml ✅ Supported
Go Modules go.mod ✅ Supported

Note

  • PyPI support includes PEP 621, PEP 735 (dependency-groups), and Poetry formats.
  • Go support includes require, replace, and exclude directives with pseudo-version handling.

Installation

From crates.io

cargo install deps-lsp

Tip

Use cargo binstall deps-lsp for faster installation without compilation.

From source

git clone https://github.com/bug-ops/deps-lsp
cd deps-lsp
cargo install --path crates/deps-lsp

Pre-built binaries

Download from GitHub Releases:

Platform Architecture Binary
Linux x86_64 deps-lsp-x86_64-unknown-linux-gnu
Linux aarch64 deps-lsp-aarch64-unknown-linux-gnu
macOS x86_64 deps-lsp-x86_64-apple-darwin
macOS Apple Silicon deps-lsp-aarch64-apple-darwin
Windows x86_64 deps-lsp-x86_64-pc-windows-msvc.exe
Windows ARM64 deps-lsp-aarch64-pc-windows-msvc.exe

Feature Flags

By default, all ecosystems are enabled. To build with specific ecosystems only:

# Only Cargo and npm support
cargo install deps-lsp --no-default-features --features "cargo,npm"

# Only Python support
cargo install deps-lsp --no-default-features --features "pypi"
Feature Ecosystem Default
cargo Cargo.toml
npm package.json
pypi pyproject.toml
go go.mod

Editor Setup

Important

Inlay hints must be enabled in your editor to see version indicators. See configuration for each editor below.

Zed

Install the Deps extension from Zed Extensions marketplace.

Enable inlay hints in Zed settings:

// settings.json
{
  "inlay_hints": {
    "enabled": true
  }
}

Neovim

require('lspconfig').deps_lsp.setup({
  cmd = { "deps-lsp", "--stdio" },
  filetypes = { "toml", "json" },
})

-- Enable inlay hints (Neovim 0.10+)
vim.lsp.inlay_hint.enable(true)

For older Neovim versions, use nvim-lsp-inlayhints.

Helix

# ~/.config/helix/languages.toml
[[language]]
name = "toml"
language-servers = ["deps-lsp"]

[[language]]
name = "json"
language-servers = ["deps-lsp"]

[language-server.deps-lsp]
command = "deps-lsp"
args = ["--stdio"]

Enable inlay hints in Helix config:

# ~/.config/helix/config.toml
[editor.lsp]
display-inlay-hints = true

VS Code

Install an LSP client extension and configure deps-lsp. Enable inlay hints:

// settings.json
{
  "editor.inlayHints.enabled": "on"
}

Configuration

Configure via LSP initialization options:

{
  "inlay_hints": {
    "enabled": true,
    "up_to_date_text": "",
    "needs_update_text": "❌ {}"
  },
  "diagnostics": {
    "outdated_severity": "hint",
    "unknown_severity": "warning",
    "yanked_severity": "warning"
  },
  "cache": {
    "enabled": true,
    "refresh_interval_secs": 300,
    "fetch_timeout_secs": 5,
    "max_concurrent_fetches": 20
  },
  "loading_indicator": {
    "enabled": true,
    "fallback_to_hints": true,
    "loading_text": ""
  },
  "cold_start": {
    "enabled": true,
    "rate_limit_ms": 100
  }
}

Configuration Reference

Section Option Default Description
cache fetch_timeout_secs 5 Per-package fetch timeout (1-300 seconds)
cache max_concurrent_fetches 20 Concurrent registry requests (1-100)
loading_indicator enabled true Show loading feedback during fetches
loading_indicator fallback_to_hints true Show loading in inlay hints if LSP progress unsupported
loading_indicator loading_text "⏳" Text shown during loading (max 100 chars)

Tip

Increase fetch_timeout_secs for slower networks. The per-dependency timeout prevents slow packages from blocking others.

Note

Cold start support ensures LSP features work immediately when your IDE restores previously opened files.

Development

Important

Requires Rust 1.89+ (Edition 2024).

Build

cargo build --workspace

Test

# Run tests with nextest
cargo nextest run

# Run tests with coverage
cargo llvm-cov nextest

# Generate HTML coverage report
cargo llvm-cov nextest --html

Lint

# Format (requires nightly for Edition 2024)
cargo +nightly fmt

# Clippy
cargo clippy --workspace -- -D warnings

# Security audit
cargo deny check

Project Structure

deps-lsp/
├── crates/
│   ├── deps-core/      # Shared traits, cache, generic handlers
│   ├── deps-cargo/     # Cargo.toml parser + crates.io registry
│   ├── deps-npm/       # package.json parser + npm registry
│   ├── deps-pypi/      # pyproject.toml parser + PyPI registry
│   ├── deps-go/        # go.mod parser + proxy.golang.org
│   ├── deps-lsp/       # Main LSP server
│   └── deps-zed/       # Zed extension (WASM)
├── .config/            # nextest configuration
└── .github/            # CI/CD workflows

Architecture

The codebase uses a trait-based architecture with the Ecosystem trait providing a unified interface for all package ecosystems:

// Each ecosystem implements the Ecosystem trait
pub trait Ecosystem: Send + Sync {
    fn id(&self) -> &'static str;
    fn display_name(&self) -> &'static str;
    fn matches_uri(&self, uri: &Uri) -> bool;
    fn registry(&self) -> Arc<dyn Registry>;
    fn formatter(&self) -> Arc<dyn EcosystemFormatter>;
    async fn parse_manifest(&self, content: &str, uri: &Uri) -> Result<ParseResult>;
}

// EcosystemRegistry discovers the right handler for any manifest file
let ecosystem = registry.get_for_uri(&uri);

Benchmarks

Run performance benchmarks with criterion:

cargo bench --workspace

View HTML report: open target/criterion/report/index.html

License

MIT

Acknowledgments

Inspired by:

About

Universal LSP server for dependency management — autocomplete, version hints, and diagnostics for Cargo.toml and package.json. Supports Zed, Neovim, Helix.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Contributors 2

  •  
  •