upd
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
.gitignoreand prunes hidden directories, without missing the dotfiles it updates - Private registries: authentication for PyPI, npm, Cargo, Go, and GitHub
- Config file: ignore or pin packages 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 --package 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:
updwithout--applyonly previews changes. Pass--applyto write updates.--check,--dry-run, and--interactivedo not require--apply.VCS-root scoping: When no path argument is given,
updscans from the nearest.gitancestor 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.
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
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file upd-0.6.4.tar.gz.
File metadata
- Download URL: upd-0.6.4.tar.gz
- Upload date:
- Size: 583.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6266857b61ae3f69e922ba657956ba5e181e6f8e8cb1eb4d0397abf59e37ba92
|
|
| MD5 |
7dd7ec57b221edc5f9222a232f888bde
|
|
| BLAKE2b-256 |
e379275ea30658b277dca8ff9d46645b43d9d5db544b9750a70306d16d9428b9
|
File details
Details for the file upd-0.6.4-py3-none-win_amd64.whl.
File metadata
- Download URL: upd-0.6.4-py3-none-win_amd64.whl
- Upload date:
- Size: 3.5 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
14aed54bd316c753574595088124dc97ba91f61a7688112da63cd0b25d8bc39f
|
|
| MD5 |
ccca33ca6ecca64b8020336b3c199474
|
|
| BLAKE2b-256 |
087f2516bd50504b0932557e58a25845c6e3595cd6b2cbf05499c277bc02af95
|
File details
Details for the file upd-0.6.4-py3-none-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: upd-0.6.4-py3-none-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 5.4 MB
- Tags: Python 3, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d7235bad45c5b403b5e2fea6566c1b83fd946d74775f04f3626142b94111a2f6
|
|
| MD5 |
ec307d1a784aacce70711ca24a46ad8e
|
|
| BLAKE2b-256 |
2623fe8093b99960a5c024e2e94df465837dad4c715b50af7e630c5c18b0a99f
|
File details
Details for the file upd-0.6.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: upd-0.6.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 5.5 MB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
723718fb52312b0e6f19e25d852f31be6f1fa702ce7149a17d62cc36ee1b750e
|
|
| MD5 |
c3ab02a809a99f260dc57fdda35cfc91
|
|
| BLAKE2b-256 |
37dd87208ca0ae1e7b7fef608e81baa4ad86521fb85bdccb76047cb3cd7c42d3
|
File details
Details for the file upd-0.6.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: upd-0.6.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 5.6 MB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9c345ee0b053b0b5a69a4605330e1253ea7b01adabbdd92aeab4bc981026fd68
|
|
| MD5 |
32df554abcda4f91ccb19a2fb009c801
|
|
| BLAKE2b-256 |
28bcbe3bc3c251c23afe29921229f71d7aca30a57752d5bbea6bc67e266eaefd
|
File details
Details for the file upd-0.6.4-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: upd-0.6.4-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 3.1 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
89ab0afbd25e1381aedef92650d78524a57e1a65f5588f0bec89b15d445f0980
|
|
| MD5 |
387a0f4a2b772f91e2833012d79057de
|
|
| BLAKE2b-256 |
f043ad8c9429e53d73d913a85a327f2e2adaad7215b0719833966db61bfe8954
|
File details
Details for the file upd-0.6.4-py3-none-macosx_10_12_x86_64.whl.
File metadata
- Download URL: upd-0.6.4-py3-none-macosx_10_12_x86_64.whl
- Upload date:
- Size: 3.3 MB
- Tags: Python 3, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3fb645b15277d3bbae4edbefa439768c7cc1554fa37af61fa35362b72a990113
|
|
| MD5 |
54e879f957ac48946d26c312cb9eed49
|
|
| BLAKE2b-256 |
8250cd5c97aa7dbdd394371b5f5441488059cffd029eacf51a0530c862c5381b
|