steadydeps
v0.1.0
Published
Policy-driven manual dependency updates for workspaces and monorepos.
Maintainers
Readme
steadydeps
Policy-driven manual dependency updates for workspaces and monorepos.
steadydeps is a library-first wrapper around npm-check-updates for teams that want a local, reviewable dependency update workflow instead of a bot-driven one.
Quick Start
Install:
pnpm add -D steadydepsCreate steadydeps.config.mjs:
import {defineConfig} from 'steadydeps';
export default defineConfig({
policy: {
cooldownDays: 7,
rules: [
{
name: 'storybook-freeze',
match: ['storybook', {glob: '@storybook/*'}],
strategy: 'exclude',
},
{
name: 'core-tooling-minor',
match: ['react', 'react-dom', 'typescript', 'vite'],
strategy: 'minor',
},
{
name: 'refresh-plugin-patch',
match: ['eslint-plugin-react-refresh'],
strategy: 'patch',
},
],
},
});Run:
steadydeps policy
steadydeps check
steadydeps update --package apps/web
pnpm installRecommended first run:
steadydeps policyto verify rule coveragesteadydeps checkto inspect candidatessteadydeps updateto changepackage.json- your package manager install command to refresh the lockfile
- your normal validation commands
When To Use It
Use steadydeps if you want:
- local/manual dependency updates instead of bot PRs
- workspace-aware package selection
- policy rules such as exclude, minor-only, patch-only, cooldown, dependency section matching, and workspace path matching
- a reusable TypeScript API in addition to a CLI
If you want automated update PRs, use Renovate. If you mainly need version consistency across a monorepo, syncpack is usually a better fit.
Features
- workspace discovery for
pnpm-workspace.yaml - fallback discovery for
package.json#workspaces - package selection by
root, package name, or relative path - string, glob, and regex package matchers
- optional dependency section matching via
dependencyTypes - optional workspace matching via
workspacePaths check,update,interactive,policy, andreportcommands- human-readable and JSON output
updateonly changespackage.json- post-action reminders after updates
CLI
steadydeps policy
steadydeps check
steadydeps report
steadydeps update
steadydeps interactiveCommon options:
steadydeps check --package root
steadydeps check --package packages/ui
steadydeps check --package @acme/ui
steadydeps update --config ./steadydeps.config.mjs
steadydeps report --json
steadydeps check --cwd ../another-repoCommand behavior:
policy- prints rule coverage and strategy counts without touching the registry
check- queries the npm registry and reports candidates without writing files
report- same execution model as
check, but summary-focused output
- same execution model as
update- updates
package.jsononly
- updates
interactive- updates
package.jsonthroughnpm-check-updatesinteractive prompts
- updates
Config
steadydeps looks for these files by default:
steadydeps.config.tssteadydeps.config.mtssteadydeps.config.ctssteadydeps.config.jssteadydeps.config.mjssteadydeps.config.cjssteadydeps.config.json
Rules are evaluated top-to-bottom. The first matching rule wins.
JavaScript config
import {defineConfig} from 'steadydeps';
export default defineConfig({
cli: {
postActions: ['pnpm install', 'pnpm test', 'pnpm build'],
},
policy: {
cooldownDays: 7,
defaultStrategy: 'latest',
rules: [
{
name: 'storybook-freeze',
match: ['storybook', {glob: '@storybook/*'}],
strategy: 'exclude',
reason: 'Review Storybook changes manually.',
},
{
name: 'core-tooling-minor',
match: ['react', 'react-dom', 'typescript', 'vite', {glob: '@typescript-eslint/*'}],
strategy: 'minor',
},
{
name: 'patch-refresh',
match: ['eslint-plugin-react-refresh'],
strategy: 'patch',
},
{
name: 'docs-workspace-rule',
match: [{regex: '^vite'}],
workspacePaths: ['apps/docs'],
dependencyTypes: ['dependencies'],
strategy: 'patch',
},
],
},
});JSON config
{
"cli": {
"postActions": ["pnpm install", "pnpm test", "pnpm build"]
},
"policy": {
"cooldownDays": 7,
"rules": [
{
"name": "storybook-freeze",
"match": ["storybook", {"glob": "@storybook/*"}],
"strategy": "exclude"
}
]
}
}Presets
Nothing is hardcoded by default. If you want a starter preset, the package exports conservativeWebPreset.
import {conservativeWebPreset} from 'steadydeps/presets/conservative-web';
export default conservativeWebPreset;Treat it as an example preset, not as the library default.
Library API
import {
applyUpdates,
checkUpdates,
defineConfig,
discoverWorkspaces,
evaluatePolicy,
generateReport,
inspectPolicy,
loadConfig,
printPolicy,
selectPackages,
} from 'steadydeps';
const config = await loadConfig({cwd: process.cwd()});
const workspaces = await discoverWorkspaces({config});
const selected = selectPackages(workspaces, ['root']);
const snapshot = evaluatePolicy({config, workspace: selected[0]});
const report = await checkUpdates({cwd: process.cwd()});
console.log(printPolicy(await inspectPolicy({cwd: process.cwd()})));
console.log(generateReport(report));Notes
steadydepsintentionally ignores.ncurc.*so your policy stays inside the steadydeps config file.updatekeeps lockfiles untouched. Run your package manager install command after updating.cooldownDaysrelies onnpm-check-updatescooldown behavior. Withtarget: latest, very frequently published packages may yield no suggestion until the latest tag becomes old enough.check,report,update, andinteractiverequire npm registry access.- rules are first-match-wins, so put narrower rules before broader ones.
--packageacceptsroot, workspace package names, and relative workspace paths.
Maintainers
Release and publish workflow notes live in docs/releasing.md.
