Skip to content

dev-five-git/dependency-check-updates

Repository files navigation

dependency-check-updates

CI Codecov deps.rs License: MIT

crates.io npm PyPI Rust 1.85+ Python 3.11+ Node

crates.io downloads npm downloads PyPI downloads

GitHub stars GitHub forks GitHub issues GitHub PRs Last commit Contributors

Dependency Check & Update — a fast, multi-ecosystem dependency updater written in Rust.

Like npm-check-updates, but for every language.

$ dcu
Checking Cargo.toml
 toml_edit  0.22  ->  0.25.4

Checking .github/workflows/CI.yml
 actions/checkout    v4  ->  v5
 actions/setup-node  v4  ->  v5

Run dcu -u to upgrade

dcu is a short alias installed alongside dependency-check-updates. Both commands are identical — use whichever you prefer.

Quick Start (Zero Install)

No install needed — run straight from your package manager's ephemeral runner:

# Node.js ecosystem
bunx @dependency-check-updates/cli
npx  @dependency-check-updates/cli

# Python ecosystem
uvx dependency-check-updates
pipx run dependency-check-updates

All four accept the same flags described in Usage.

Features

  • Multi-ecosystempackage.json, Cargo.toml, pyproject.toml, and .github/workflows/*.yml all handled by a single binary
  • Format-preserving — surgical byte-range patching for JSON / YAML; toml_edit for TOML. Your indentation, comments, trailing newlines, and key ordering stay intact
  • Fast — concurrent registry lookups across all manifests via futures::join_all
  • Smart range checking — skips false positives where the resolved version already satisfies the current range (^3 already covers 3.5.1)
  • Deep scan-d recursively finds manifests in monorepos, respecting .gitignore
  • ncu-compatible UX — the same flags you already know from npm-check-updates
  • Short alias — type dcu instead of dependency-check-updates; both are installed by every distribution
  • CI-friendly-e 2 exits non-zero when updates exist; --format json emits machine-readable output

Supported Ecosystems

Ecosystem Manifest Registry Package
Node.js package.json npm @dependency-check-updates/cli
Rust Cargo.toml crates.io dependency-check-updates
Python pyproject.toml PyPI dependency-check-updates
GitHub Actions .github/workflows/*.yml, action.yml GitHub Tags API (built-in)

GitHub Actions specifics

  • Discovers every *.yml / *.yaml under .github/workflows/ and any action.yml / action.yaml at the repo root automatically. Composite actions nested under .github/actions/**/ are picked up with -d.
  • Scans uses: owner/repo@ref directives. Refs without version digits — @main, @master, branch names, and full commit SHAs — are left untouched on purpose; they pin a moving target intentionally.
  • Tag prefix is preserved: @v5 updates to @v6 (major float), @v5.1.0 updates to @v6.0.0 (full precision). Bare semver without the v (@1.2.3, @5) is recognised and tracked the same way.
  • Duplicate rows are collapsed in the output — if actions/checkout@v5 appears in 12 jobs, you see one row, not twelve. The patch engine still updates every occurrence in the file.
  • Rate limit: unauthenticated runs use GitHub's 60 req/hr ceiling. Hitting it produces an explicit error pointing to the fix — set GITHUB_TOKEN (or GH_TOKEN) in your environment to raise the limit to 5 000 req/hr.
  • Tag fetch is bounded to the first 100 tags per action (newest-first). This comfortably covers every mainstream action; deliberately not paginating keeps API consumption predictable so deep scans don't spike into the rate-limit ceiling.

Installation

Every distribution below ships the exact same binary. Pick whichever matches your toolchain.

Rust (Cargo)

cargo install dependency-check-updates

Installs commands: dependency-check-updates and dcu (short alias).

Node.js (npm / bun / pnpm / yarn)

Permanent global install:

npm  install   -g @dependency-check-updates/cli
bun  add       -g @dependency-check-updates/cli
pnpm add       -g @dependency-check-updates/cli
yarn global add   @dependency-check-updates/cli

Installs commands: dependency-check-updates and dcu (short alias).

One-off execution (no install):

bunx @dependency-check-updates/cli [flags]
npx  @dependency-check-updates/cli [flags]

Python (pip / uv / pipx)

Permanent isolated install:

pipx install dependency-check-updates
uv tool install dependency-check-updates

Install inside a virtualenv:

pip    install dependency-check-updates
uv pip install dependency-check-updates

Installs commands: dependency-check-updates and dcu (short alias).

One-off execution (no install):

uvx dependency-check-updates [flags]
pipx run dependency-check-updates [flags]

Usage

Run from a directory containing at least one of package.json, Cargo.toml, pyproject.toml, or .github/workflows/*.yml. Every supported manifest in the current directory is auto-detected.

All examples below use the short dcu alias. The long form dependency-check-updates works identically.

Basic

# Check for outdated dependencies (read-only, nothing is written)
dcu

# Apply updates in place (format-preserving)
dcu -u

# Recursively scan subdirectories (monorepo-friendly, respects .gitignore)
dcu -d
dcu -d -u

All Options

Usage: dcu [OPTIONS] [FILTER]...
Flag Description Default
[FILTER]... Positional package names to include (allowlist; repeatable) (all)
-u, --upgrade Write updated versions back to the manifest file off
-d, --deep Recursively scan subdirectories, respecting .gitignore off
-t, --target <LEVEL> Version target: patch · minor · latest · newest · greatest latest
-x, --reject <PATTERN> Exclude packages by name (repeatable)
--manifest <PATH> Operate on a single specific manifest file (auto)
--format <FORMAT> Output format: table or json table
--remove-lockfile Delete lockfiles next to each manifest so the package manager re-resolves transitive deps on the next install off
--remove-installed Delete installed-dependency directories next to each manifest for a clean install off
--rm Shortcut for --remove-lockfile --remove-installed — wipes both in one go off
-e, --error-level <N> 1 = always exit 0 · 2 = exit 1 when updates exist (CI gate) 1
-v, --verbose Increase verbosity: -v info · -vv debug · -vvv trace off
-h, --help Print help
-V, --version Print version

-t, --target values

Value Behavior
patch Only patch bumps (e.g., 1.0.1 → 1.0.2)
minor Patch + minor bumps (e.g., 1.0.0 → 1.1.0)
latest Latest stable version; prereleases are skipped (default)
newest Most recently published version by publish date (npm time, crates.io created_at, PyPI upload time). For GitHub Actions this falls back to greatest — the Tags API exposes no per-tag dates.
greatest Highest version number, including prereleases

All five targets apply to every ecosystem, including Python (pyproject.toml / PyPI), which resolves PEP 440 versions from the full release list.

Examples

# Target specific update level
dcu -t patch           # patch only
dcu -t minor           # minor + patch
dcu -t latest          # default: latest stable
dcu -t greatest        # include prereleases

# Filter packages — positional args act as an include-list
dcu react eslint       # only check react and eslint
dcu -x typescript      # exclude typescript
dcu -x typescript -x lodash

# Filter GitHub Actions by owner — same filter syntax works across ecosystems
dcu actions            # only actions/checkout, actions/setup-node, …

# Operate on a specific manifest
dcu --manifest path/to/Cargo.toml
dcu --manifest apps/web/package.json
dcu --manifest .github/workflows/CI.yml

# Machine-readable output for scripting/CI
dcu --format json

# CI gate: exit 1 if any updates are available
dcu -e 2

# Verbose logging (accumulating)
dcu -v    # info
dcu -vv   # debug
dcu -vvv  # trace

# Combining flags — recursive, patch-only upgrade in a monorepo
dcu -d -u -t patch

# Force a full transitive refresh: bump manifests, wipe lockfiles, wipe
# installed copies. The next `bun install` / `cargo build` / `uv sync`
# rebuilds the dep tree from scratch and picks up the latest dep-of-dep.
dcu -u --rm                                      # shortcut for both removals
dcu -d -u --rm                                   # same, monorepo-wide
dcu -u --remove-lockfile                         # lockfiles only, keep installed
dcu -u --remove-installed                        # installed only, keep lockfiles

# Files / directories removed (per manifest discovered):
#   package.json   → bun.lock, bun.lockb, package-lock.json, pnpm-lock.yaml,
#                    yarn.lock, node_modules/
#   Cargo.toml     → Cargo.lock, target/
#   pyproject.toml → uv.lock, poetry.lock, Pipfile.lock, .venv/, venv/

# GitHub Actions: pin a higher rate limit by exporting a token
GITHUB_TOKEN=ghp_xxx dcu -d -u

Zero-Install Examples

Every example above works identically via the ephemeral runners, too:

bunx @dependency-check-updates/cli                  # check
bunx @dependency-check-updates/cli -u               # apply updates
bunx @dependency-check-updates/cli -d -t minor      # deep scan, minor bumps
bunx @dependency-check-updates/cli react eslint     # filter
npx  @dependency-check-updates/cli --format json

uvx dependency-check-updates
uvx dependency-check-updates -d -u -t patch
pipx run dependency-check-updates --format json

Architecture

Follows the changepacks pattern — one crate per language ecosystem, with bridge crates for cross-language distribution:

.
├── crates/
│   ├── cli/           # Binary + async CLI orchestration (installs `dcu` + `dependency-check-updates`)
│   ├── core/          # Shared traits (ManifestHandler, RegistryClient, Scanner)
│   ├── node/          # Node.js: package.json parser + npm registry
│   ├── rust/          # Rust: Cargo.toml parser (toml_edit) + crates.io
│   ├── python/        # Python: pyproject.toml parser (toml_edit) + PyPI
│   └── github/        # GitHub Actions: workflow YAML parser + GitHub Tags API
├── bridge/
│   ├── node/          # napi-rs N-API binding → npm: @dependency-check-updates/cli
│   └── python/        # maturin bin binding → PyPI: dependency-check-updates
├── Cargo.toml         # Workspace root
└── package.json       # Bun workspace (build/lint/test scripts)

Format Preservation

  • JSON (package.json): Surgical byte-range replacement — finds exact byte offsets of version values and replaces only those bytes. Indent, line endings, trailing newline, and key ordering are preserved byte-for-byte.
  • TOML (Cargo.toml, pyproject.toml): toml_edit document model preserves comments, table ordering, inline-table formatting, and whitespace.
  • YAML (.github/workflows/*.yml, action.yml): Line-based uses: scanning with byte-range replacement of only the @ref portion. Anchors, comments, blank lines, and unrelated @main / @<sha> pins are never touched.

Shared Traits

Each ecosystem crate implements two core traits from dependency-check-updates-core:

  • ManifestHandler — parse manifests, collect dependencies, apply format-preserving updates
  • RegistryClient — resolve versions from package registries with concurrency control

Range Satisfaction

Before reporting an update, the resolver checks whether the selected version already satisfies the current range (e.g., ^3 already covers 3.5.1). This eliminates the false positives that plague naive string comparison.

Development

Build prerequisites:

  • Rust 1.85+ (stable toolchain)
  • Bun 1.0+ (or Node.js 18+ with npm)
  • Python 3.11+ with maturin (only for the Python wheel step)
  • Windows: Visual Studio 2022 Build Tools (MSVC linker)
# First-time setup: install JS toolchain deps (@napi-rs/cli, etc.)
bun install

# Build everything (native CLI + napi .node + maturin wheel)
bun run build

# Dev build (faster, unoptimized)
bun run build:dev

# Lint (cargo clippy + rustfmt + bun workspace lints)
bun run lint
bun run lint:fix

# Test (cargo test --workspace + bun workspace tests)
bun run test

# Run CLI from source
bun run run -- --help
bun run run -- --manifest Cargo.toml -v
bun run run:release -- -d

Inspirations

  • npm-check-updates — the original ncu that inspired this tool's UX and flag design
  • changepacks — the workspace architecture pattern (crates/* + bridge/*), multi-language bridge distribution via napi-rs and maturin, and the overall project structure

License

MIT

About

Find and update newer versions of dependencies across your package manifests

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages