Skip to main content

upd logo

upd

crates.io PyPI CI License: MIT

A fast dependency updater for Python, Node.js, Rust, Go, Ruby, .NET, Terraform, GitHub Actions, pre-commit, and Mise projects, written in Rust.

Quick Start

# Preview changes without modifying files (default)
uvx upd

# Apply updates
uvx upd --apply

# Or with pipx
pipx run upd --apply

Features

  • Multi-ecosystem: Python, Node.js, Rust, Go, Ruby, .NET, Terraform, GitHub Actions, pre-commit, Mise/asdf
  • Dry-run by default: nothing is written without --apply
  • Fast: parallel registry requests, with a 24-hour version cache
  • Constraint-aware: respects >=2.0,<3 (Python), ~> 7.1 (Ruby), and ^2.0.0 / ~2.0.0 (npm, Cargo)
  • Format-preserving: keeps formatting, comments, and structure
  • Update filters: --only-bump, --max-bump, --package, --lang, or approve one by one with -i
  • Major warnings: breaking changes are flagged with (MAJOR)
  • Pre-release aware: updates pre-releases to newer pre-releases
  • Cooldown: hold back releases younger than N days, against supply-chain attacks
  • Security auditing: OSV vulnerability scanning with auto-fix and SARIF output
  • Check mode: exit 1 if updates are available (for CI and pre-commit)
  • Gitignore-aware: honors .gitignore and prunes hidden directories, without missing the dotfiles it updates
  • Private registries: authentication for PyPI, npm, Cargo, Go, and GitHub
  • Config file: include or exclude paths, ignore packages, and pin versions via .updrc.toml

Installation

From crates.io

cargo install upd

# or with cargo-binstall (faster, pre-built binary)
cargo binstall upd

From PyPI

pip install upd
# or with uv
uv pip install upd

If you installed an earlier release under the old distribution name, migrate once with pip uninstall upd-cli && pip install upd. The upd-cli command remains available as a compatibility alias.

From source

git clone https://github.com/rvben/upd
cd upd
cargo install --path .

Usage

# Preview changes without modifying files (default when no --apply)
upd

# Apply updates to files
upd --apply

# Limit to specific files or directories
upd --apply requirements.txt pyproject.toml

# Approve updates one by one
upd -i

# Only the packages you name
upd -p requests,flask

# Cap the bump level (allow patch + minor, skip major). Updates above the
# ceiling are reported as held back, never as up to date, and do not
# change the exit code.
upd --max-bump minor

# Restrict to exactly one level (repeatable, comma-separated)
upd --only-bump major

# One ecosystem at a time: python, node, rust, go, ruby, dot-net,
# terraform, actions, pre-commit, mise, annotated
upd --lang python

# Exit 1 if anything is outdated (for CI and pre-commit)
upd --check

# Regenerate lockfiles after writing
upd --apply --lock

# Print the effective configuration and exit
upd --show-config

upd --help lists every flag; Stability documents the ones that are contractual, and upd schema emits the whole interface as JSON.

Dry-run by default: upd without --apply only previews changes. Pass --apply to write updates. --check, --dry-run, and --interactive do not require --apply.

VCS-root scoping: When no path argument is given, upd scans from the nearest .git ancestor directory rather than the current working directory. This prevents accidental rewrites when CWD is a subdirectory inside a repository.

Commands

upd --version      # Print version
upd self-update    # Check for upd updates
upd clean-cache    # Clear the version cache
upd align          # Align versions across files (--check exits 1 on misalignment)
upd audit          # Scan for known vulnerabilities (exit 6 if found)
upd schema         # Machine-readable interface description

Example Output

.pre-commit-config.yaml:37: Would update pre-commit/pre-commit-hooks v4.6.0 → v6.0.0 (MAJOR)
.github/workflows/ci.yml:16: Would update actions/checkout v4 → v6 (MAJOR)
.github/workflows/ci.yml:18: Would update jdx/mise-action v2 → v4 (MAJOR)
.mise.toml:8: Would update rust 1.91.1 → 1.94.0
Cargo.toml:33: Would update clap 4.5.53 → 4.6.0
Cargo.toml:36: Would update tokio 1.48.0 → 1.50.0

Would update 6 package(s) (2 major, 3 minor, 1 patch) in 4 file(s), 8 up to date

Output includes clickable file:line: locations (recognized by VS Code, iTerm2, and modern terminals).

Version Constraints

upd respects version constraints in your dependency files:

Constraint Behavior
>=2.0,<3 Updates within 2.x range only
^2.0.0 Updates within 2.x range (npm/Cargo); never crosses the major bound
~2.0.0 Updates within 2.0.x range (npm); ~2.0.0 (Cargo) stays within 2.0.x
~> 7.1 Updates within 7.x range (Ruby pessimistic)
>=2.0 Updates to any version >= 2.0
==2.0.0 Updates the exact pin to the latest version (e.g. ==2.0.0==3.1.5). To freeze a package, use [pin] or ignore in .updrc.toml.

For npm, comparator ranges such as ">=1.0.0 <2.0.0" are rewritten with a bump strategy: the lower bound moves to the highest version satisfying the constraint, preserving the upper bound. Hyphen ("1 - 2") and OR ("^1 || ^2") ranges are reported as warnings and left untouched rather than rewritten wrongly.

Annotated Version Pins

Files without a dependency-manifest format can carry a trailing annotation:

shinyhub_version: "0.11.16"  # upd: pypi shinyhub

Directory walks scan annotations in Makefile, makefile, GNUmakefile, justfile, Justfile, *.mk, *.sh, and *.bash. Any file passed explicitly is scanned as annotated. To add other files to normal repository discovery, use repository-relative globs in .updrc.toml:

include = ["ansible/roles/*/vars/*.yml", "docker-compose.yml"]
exclude = ["**/archive/**"] # exclude wins over include

An include never changes a recognized manifest's parser: for example, a matching main.tf remains Terraform. Use --verbose to diagnose an upd: marker in an otherwise undiscovered UTF-8 text file up to 1 MiB.

Version Precision

By default, upd preserves version precision from the original file:

# Original file has 2-component versions
flask>=2.0        →  flask>=3.1        (not 3.1.5)
django>=4         →  django>=6         (not 6.0.0)

# Original file has 3-component versions
requests>=2.0.0   →  requests>=2.32.5

# GitHub Actions major-only tags
actions/checkout@v3  →  actions/checkout@v4  (not @v4.2.0)

Use --full-precision to always output full semver versions:

upd --full-precision
flask>=2.0        →  flask>=3.1.5
django>=4         →  django>=6.0.0
requests>=2.0.0   →  requests>=2.32.5

Version Alignment

In monorepos or projects with multiple dependency files, the same package might have different versions:

# requirements.txt
requests==2.28.0

# requirements-dev.txt
requests==2.31.0

# services/api/requirements.txt
requests==2.25.0

upd align updates every occurrence to the highest version found:

upd align              # Align all packages to highest version
upd align --dry-run    # Preview changes
upd align --check      # Exit 1 if misalignments (for CI)
upd align --lang python # Align only Python packages

It only aligns within one ecosystem, skips packages with upper bound constraints (e.g. >=2.0,<3.0) to avoid breaking them, and ignores pre-release versions when finding the highest version.

Pre-commit Integration

Add upd to your .pre-commit-config.yaml:

repos:
  - repo: https://github.com/rvben/upd-pre-commit
    rev: v0.0.24
    hooks:
      - id: upd-check
        # Optional: only check specific ecosystems
        # args: ['--lang', 'python']

Available hooks:

Hook ID Description
upd-check Fail if any dependencies are outdated
upd-check-major Fail only on major (breaking) updates

Both hooks run on pre-push by default. Uses language: python which installs upd from PyPI automatically, so no manual installation is needed.

Documentation

Everything you look up rather than read lives in docs/.

Releases

Vership workflow, publication guarantees, automated integration pins, and safe retry procedures. → docs/releases.md

Supported files

Every file upd discovers, per ecosystem, plus annotated version pins in files it does not otherwise understand. → docs/ecosystems.md

Security auditing

OSV vulnerability scanning, --fix-audit, SARIF output, and CI integration. → docs/audit.md

Configuration file

.updrc.toml discovery order and every key it accepts. → docs/configuration.md

Cooldown (minimum release age)

Hold back versions published less than N days ago, per ecosystem. → docs/configuration.md#cooldown-minimum-release-age

Caching

Where the 24-hour version cache lives and how to clear or bypass it. → docs/configuration.md#caching

Environment variables

Every variable upd reads, in one table. → docs/configuration.md#environment-variables

Private repositories

Credential detection for PyPI, npm, Cargo, Go, and GitHub, including private indexes declared in pyproject.toml. → docs/private-registries.md

GitHub pull requests

Run any supported dependency updates as one rolling GitHub PR, with immutable Action SHA verification, validation, artifact reporting, and opt-in auto-merge. → docs/github-actions.md

GitLab merge requests

Run scheduled dependency updates as one rolling GitLab MR, with validation, lease-protected branch updates, and explicitly opt-in GitLab-native auto-merge. → docs/gitlab.md

Stability

The stable CLI surface, exit codes, --lock commands, and output guarantees. → docs/stability.md

Development

# Build
make build

# Run tests
make test

# Lint
make lint

# Format
make fmt

# All checks
make check

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

upd-0.7.1.tar.gz (608.8 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

upd-0.7.1-py3-none-win_amd64.whl (3.6 MB view details)

Uploaded Python 3Windows x86-64

upd-0.7.1-py3-none-musllinux_1_2_x86_64.whl (5.5 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

upd-0.7.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.5 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

upd-0.7.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (5.6 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

upd-0.7.1-py3-none-macosx_11_0_arm64.whl (3.2 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

upd-0.7.1-py3-none-macosx_10_12_x86_64.whl (3.4 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file upd-0.7.1.tar.gz.

File metadata

  • Download URL: upd-0.7.1.tar.gz
  • Upload date:
  • Size: 608.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for upd-0.7.1.tar.gz
Algorithm Hash digest
SHA256 cae7f2fb82a59ea2cdb9721e0e63d4fad7bf9f0bf410fbe88ee2d07d9ed3f4dc
MD5 4db770bf9f2ed43eed1fb8507c7e559d
BLAKE2b-256 9a9b19b691a1dfa5883f04ef6ee9ed652c2496faa94fd4c5f64951f2f44bc749

See more details on using hashes here.

File details

Details for the file upd-0.7.1-py3-none-win_amd64.whl.

File metadata

  • Download URL: upd-0.7.1-py3-none-win_amd64.whl
  • Upload date:
  • Size: 3.6 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for upd-0.7.1-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 8817d058386e2e490282cdf6b31a15bf462c76805fd1be945b446000fd99bd64
MD5 e31481f711479df7da65b9091e4355f7
BLAKE2b-256 7f496ca41122de88d5f5656dc237bbc35b2ef0c4d6fa297a0261091e2aea5baf

See more details on using hashes here.

File details

Details for the file upd-0.7.1-py3-none-musllinux_1_2_x86_64.whl.

File metadata

  • Download URL: upd-0.7.1-py3-none-musllinux_1_2_x86_64.whl
  • Upload date:
  • Size: 5.5 MB
  • Tags: Python 3, musllinux: musl 1.2+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for upd-0.7.1-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 d24d78c95750c67df0696b2fee200c9c4c164102a8cfaf00e55f2e57075a91c0
MD5 b5f912f5d32dac51fba3ec3f15d71b6c
BLAKE2b-256 2e91741244fd9cb03bf4eda19b0d9636c87634090cb20fc24bbe32ea638249c2

See more details on using hashes here.

File details

Details for the file upd-0.7.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for upd-0.7.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 bd73e8120ec84a16f0b857dd98e26ac2bb808cf0e461f702e4e5cf1d373162b5
MD5 1a5ad4e79afb5fcb66f0a9c2abf4da90
BLAKE2b-256 c99aa1e2e0b558a1315b8b19c7d7520da72bdf18fa8d6ddae6ec718fbd90e67a

See more details on using hashes here.

File details

Details for the file upd-0.7.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for upd-0.7.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 b3d53d8948ccd3f011b86c447d8fed21ed297e28a2e43921333cc8d1544ac00d
MD5 e0724651fcc761faa69af490c4345256
BLAKE2b-256 400d0dd82102b4c3ea1b8633d5678d464aaba2b2d7793ed48f1b508193555d4b

See more details on using hashes here.

File details

Details for the file upd-0.7.1-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: upd-0.7.1-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 3.2 MB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for upd-0.7.1-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 19b5683172bceb0592632cd387b6ecb261e70295583982884fa8a5df945237e3
MD5 e70d6d3fb6d0f15ca86c1344035b1603
BLAKE2b-256 db0c9087ee1a08869b88ff55a848c1c2de6819ea2568a1cc5d9b52f3359d6f94

See more details on using hashes here.

File details

Details for the file upd-0.7.1-py3-none-macosx_10_12_x86_64.whl.

File metadata

  • Download URL: upd-0.7.1-py3-none-macosx_10_12_x86_64.whl
  • Upload date:
  • Size: 3.4 MB
  • Tags: Python 3, macOS 10.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for upd-0.7.1-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 dc948b84d56abb6efe215b8db695759093b35319150e1bf6043387c758fdb101
MD5 0b67cc0f74d88f4c5019d1f817221f33
BLAKE2b-256 ce8715ac09cb89ebead1a824aa746a2c99b2078e26c755ce3a867d5a2010fb95

See more details on using hashes here.

Release history Release notifications | RSS feed

0.11.5

7 files

0.11.4

7 files

0.11.3

7 files

0.11.2

7 files

0.11.1

7 files

0.11.0

7 files

0.10.4

7 files

0.10.3

7 files

0.10.2

7 files

0.10.1

7 files

0.10.0

7 files

0.9.2

7 files

0.9.1

7 files

0.9.0

7 files

0.8.8

7 files

0.8.7

7 files

0.8.6

7 files

0.8.5

7 files

0.8.4

7 files

0.8.3

7 files

0.8.2

7 files

0.8.1

7 files

0.8.0

7 files

This release

0.7.1 This release

7 files

0.7.0

7 files

0.6.5

7 files

0.6.4

7 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page