Profile
Back to NewsBack
GitHub Trending 6 min
Reader Mode
silverwind/updates: CLI to update npm, uv, cargo, go, docker and actions dependencies

silverwind/updates: CLI to update npm, uv, cargo, go, docker and actions dependencies

14 hours ago

updates

</a> </a> </a> </a>

updates is a CLI tool that checks for dependency updates, with zero dependencies.

Supported files

  • package.json, pnpm-workspace.yaml - npm dependencies
  • pyproject.toml - uv dependencies, including build-system.requires and tool.uv.dev-dependencies
  • go.mod, go.work - go dependencies
  • Cargo.toml - rust dependencies, including workspaces
  • .{github,gitea,forgejo}/{workflows,actions}, workflow-templates, action.{yml,yaml} - actions and docker images
  • {Docker,Container}file, .{Docker,Container}file, compose.{yml,yaml}, docker-.{yml,yaml} - docker images
  • Makefile, .mk, .sh - go tool versions in go install paths and docker image tags

Usage

# check for updates
pnpm dlx updates

update package.json and install new dependencies

pnpm dlx updates -u && pnpm i

Options

|Option|Description| |:-|:-| |-u, --update|Update versions and write dependency file| |-f, --file |File or directory to use, defaults to current directory| |-N, --include-paths |Only use paths matching the globs| |-X, --exclude-paths |Skip paths matching the globs| |-M, --modes |Which modes to enable. Either npm, pypi, go, cargo, actions, docker, make, shell. Default: all| |-i, --include |Include only given dependencies| |-e, --exclude |Exclude given dependencies| |-l, --pin |Pin dependency to given semver range| |-C, --cooldown |Minimum dependency age, like 12h, 7d, 2w, 5m (30 days), 1y (365 days). A bare number is days| |-p, --prerelease []|Consider prereleases, implying --greatest| |-R, --release []|Never consider prereleases| |-g, --greatest []|Ignore the latest tag and take the greatest release| |-t, --types |Dependency types to update| |-P, --patch []|Consider only up to semver-patch| |-m, --minor []|Consider only up to semver-minor| |-d, --allow-downgrade []|Allow downgrading onto a lower latest tag| |-s, --sockets |Maximum number of parallel HTTP sockets opened. Default: 50| |-T, --timeout |Network request timeout in ms, go probes use half. Default: 5000| |-r, --registry |Override npm registry URL| |-L, --login |Verify and store a forge API token| |-O, --logout |Remove a stored forge API token| |-I, --indirect|Include indirect Go dependencies| |-E, --error-on-outdated|Exit with code 2 when updates are available and 0 when not| |-U, --error-on-unchanged|Exit with code 0 when updates are available and 2 when not| |-j, --json|Output a JSON object| |-x, --no-cache|Disable HTTP cache| |-c, --color|Force color output| |-n, --no-color|Disable color output| |-v, --version|Print the version| |-V, --verbose|Print verbose output to stderr| |-h, --help|Print the help|

Options taking multiple arguments accept comma-separated values or repetition. An option with an optional dep argument applies to all dependencies when the argument is omitted. dep matches globs like foo* or regexes wrapped in slashes like '/^foo/', except for --pin, which takes an exact name.

Path filters also apply to workspace members, except files passed with --file.

A failed lookup is reported on its own, does not hold back the other results and exits with code 1, ahead of -E and -U. With -j, failures are listed in an errors array next to results.

Config File

Configure via updates.config.{js,ts,mjs,mts}. Each manifest uses the nearest config above it, and workspace members use the workspace root config. CLI arguments win over configured values, including include, exclude and pin.

import type {Config} from "updates";

export default { pin: { "typescript": "^6", }, } satisfies Config;

Config Options

Mirrors the CLI options in camelCase, with --file as files, plus:

  • overrides Array\: Per-package option overrides (see Overrides)
  • inherit object: Fields to inherit from other tools' configs (see Renovate config)
include, exclude and the dep options take Array, pin takes a Record keyed by exact dependency name, files, modes, includePaths and excludePaths take Array.

Overrides

overrides applies options to a subset of dependencies. Each entry takes include and/or exclude patterns, omit include to match all, plus any of cooldown, greatest, prerelease, release, patch, minor, allowDowngrade. An override beats the top-level option and the last match wins.

import type {Config} from "updates";

export default { cooldown: "7d", overrides: [ {include: ["@myorg/*"], cooldown: 0}, // no cooldown for your own scope {include: [/^@aws-sdk/], cooldown: "14d"}, // longer cooldown for a noisy publisher {exclude: ["typescript"], greatest: true}, // greatest for everything but typescript ], } satisfies Config;

Renovate config

A Renovate renovate.json, renovate.jsonc or renovate.json5 is picked up automatically, inheriting ignoreDeps, enabled and allowedVersions from matching local packageRules as include/exclude/pin. Exact-name allowedVersions ranges become pin ceilings that never downgrade. Local fields are imported when extends is present, but preset contents are not resolved. minimumReleaseAge is not inherited unless opted in:

export default {
  inherit: {
    renovate: {cooldown: true},
  },
} satisfies Config;

Values in updates.config override anything inherited.

API

updates can be used as a library and accepts all config options:

import {updates} from "updates";

const output = await updates({ files: ["package.json"], include: [/^react/], modes: ["npm"], }); //=> { //=> "results": { //=> "npm": { //=> "dependencies": { //=> "react": { //=> "old": "18.0.0", //=> "new": "19.2.0", //=> "info": "https://github.com/facebook/react", //=> "age": "2d" //=> } //=> } //=> } //=> } //=> }

Environment Variables

|Variable|Description| |:-|:-| |UPDATES_FORGE_TOKENS|Comma-separated list of host:token pairs for forge APIs, e.g. github.com:ghp_xxx,localhost:3500:tok_xxx. The host must match the URL exactly, port included| |UPDATES_GITHUB_API_TOKEN|GitHub API token, with GITHUB_API_TOKEN, GH_TOKEN, GITHUB_TOKEN and HOMEBREW_GITHUB_API_TOKEN as fallbacks, in that order. Only ever sent to GitHub itself| |pnpm_config__auth|npm registry credentials as pnpm reads them, e.g. {"https://registry.npmjs.org":{"@":{"authToken":"npm-token"},"@org":{"authToken":"org-token"}}}. @ is the registry-wide token, @org binds a token and registry to that scope. The _auth key of pnpm's global config.yaml is read the same way| |GOPROXY|Go module proxy list, honored as go itself does. Default: https://proxy.golang.org,direct| |GONOPROXY|Comma-separated list of Go module patterns to fetch directly, bypassing the proxy| |GOPRIVATE|Fallback for GONOPROXY when not set|

updates --login reads a token from stdin or a prompt and stores it for that forge, updates --logout removes it. A host in UPDATES_FORGE_TOKENS wins over a stored token, which wins over the GitHub tokens.

npm registries resolve in pnpm's order: --registry, then pnpm_config__auth, pnpm-workspace.yaml, the global config.yaml, its _auth routes, and finally .npmrc. A scope-specific token wins over a registry-wide one.

© silverwind, distributed under BSD licence

Chat with me