An interactive CLI that checks your package-lock.json for outdated npm packages, scans for security vulnerabilities, and lets you pick which ones to update — all from your terminal. Node-version-aware: if the latest version of a package requires a newer Node than what's active, it suggests the best compatible version instead.
- Detects your active Node version (
.nvmrc→.node-version→node --version) - Reads
.npmrcfor custom registry configuration (scoped registries, auth tokens) - Parses
package-lock.json(v1/v2/v3) andpackage.jsonfor direct dependencies - Fetches the npm registry concurrently for newer versions
- Checks security advisories via the OSV database (includes GitHub Security Advisories)
- Presents an interactive TUI to select packages for update
- Generates and optionally executes
npm installcommands (splitting prod/dev, keeping each dependency's^/~/exact range style)
brew install jee4nc/tap/packwatchscoop bucket add packwatch https://github.com/jee4nc/scoop-bucket
scoop install packwatchDownload the .deb package from the Releases page:
sudo dpkg -i packwatch_*.debDownload from the Releases page for your platform:
| Platform | Archive |
|---|---|
| macOS arm64 | packwatch_darwin_arm64.tar.gz |
| macOS amd64 | packwatch_darwin_amd64.tar.gz |
| Linux arm64 | packwatch_linux_arm64.tar.gz |
| Linux amd64 | packwatch_linux_amd64.tar.gz |
| Windows amd64 | packwatch_windows_amd64.zip |
| Windows arm64 | packwatch_windows_arm64.zip |
# Build and install to $GOPATH/bin
make install
# Or just build
make build- Node.js installed on your system
- A
package-lock.jsonin the current directory
# Run in any Node.js project
packwatch
# Only check production dependencies
packwatch --prod-only
# Only check dev dependencies
packwatch --dev-only
# Output as JSON (no interactive TUI)
packwatch --json
# Disable colors
packwatch --no-color
# Detect unused dependencies
packwatch --unused
# Show version
packwatch --version 📦 packwatch v1.0.0
⬢ Node 20.11.0 from .nvmrc
🔒 Lockfile v3 — 42 direct dependencies
🔍 Checking npm registry for 42 packages...
████████████████████████████████ 42/42
🛡️ Checking security advisories for 42 packages...
████████████████████████████████ 42/42
📊 5 updates available · 2 vulnerable (1 HIGH, 1 MEDIUM)
┌─────────────────────────────────────────────────────────┐
│ ▶ express 4.18.2 → 4.21.0 minor │
│ lodash 4.17.20 → 4.17.21 patch 🛡️ HIGH│
│ axios 1.6.0 → 1.7.9 minor │
│ typescript 5.3.3 → 5.7.2 minor dev │
│ webpack 5.89.0 → 5.97.0 minor dev │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ react 18.3.1 up-to-date │
└─────────────────────────────────────────────────────────┘
When the latest version of a package requires a newer Node than what's active, packwatch won't blindly suggest it. Instead, it walks versions newest-to-oldest and suggests the best one compatible with your Node:
⚠️ next 14.2.3 → 15.1.0
latest (15.1.0) requires Node >=18.18.0; suggesting 14.2.28 instead
The same applies to peer dependencies: if updating a package would break the peerDependencies of another installed package, packwatch suggests the newest version that satisfies them. Deprecated versions and versions above the latest dist-tag are never suggested.
When you're already on the newest compatible version, the package is listed as held back instead of offering an update that would break:
⏸ 1 held back by Node/peer constraints:
• eslint: latest (10.11.0) requires Node >=20.19.0; already on newest compatible version
A partial version in .nvmrc / .node-version (e.g. 20) is resolved like a version manager would: to your active node if it's in that line, otherwise to the latest release of that line from nodejs.org.
Peer dependencies are checked in both directions and across the whole plan. Packages that pin each other (e.g. vitest and @vitest/coverage-v8, react and react-dom) are evaluated together: if their new versions are compatible with each other, both are suggested and marked update together. Selecting one selects its partners, and packwatch adds any missing partner before running npm install.
@types/node is kept on the Node major your project targets — the minimum major in engines.node, or your active Node if not set — since its major version tracks the Node API it describes.
packwatch reads your user and project .npmrc: registry, scoped registries (@scope:registry=...) and _authToken entries (with ${ENV_VAR} expansion). Tokens are matched like npm does: a token configured for a parent path (e.g. //company.jfrog.io/artifactory/api/npm/) also applies to every registry below it.
Use --json for CI pipelines or scripting. Stdout contains only the JSON document; progress and messages go to stderr.
# List all vulnerable packages
packwatch --json | jq '.packages[] | select(.vulnCount > 0)'
# List major updates only
packwatch --json | jq '.packages[] | select(.updateType=="major")'# Build for current platform
make build
# Run tests
make test
# Lint (fmt + vet)
make lint
# Cross-compile for all platforms
make releaseBinaries are output to bin/ with optimized flags (-s -w) for minimal size.