TL;DR
taze is the modern dependency update checker — by Anthony Fu, supports monorepos, interactive mode, filters by major/minor/patch, works with pnpm/npm/yarn. npm-check-updates (ncu) is the classic updater — upgrades package.json versions, semver range filtering, extensive CLI options, the most widely used. npm-check is the interactive updater — shows unused deps, has a TUI for selecting updates, color-coded output. In 2026: taze for modern monorepo workflows, npm-check-updates for automated CI pipelines, npm-check for interactive dependency review.
Key Takeaways
- taze: ~200K weekly downloads — monorepo support, interactive, modern DX, by Anthony Fu
- npm-check-updates (ncu): ~2M weekly downloads — the standard, CI-friendly, extensive filters
- npm-check: ~500K weekly downloads — interactive TUI, unused dep detection, color output
- All three check for outdated dependencies and can update package.json
- taze has the best monorepo support (workspaces, recursive)
- npm-check-updates has the most filtering options (semver ranges, regex)
Quick Comparison
| taze | npm-check-updates | npm-check | |
|---|---|---|---|
| Weekly Downloads | ~500K | ~3M | ~600K |
| Interactive UI | ❌ | ✅ (-i) | ✅ |
| Monorepo support | ✅ (--recursive) | ✅ | ❌ |
| Filter by semver | ✅ | ✅ | ✅ |
| Config file | ✅ (.taze.config) | ✅ (.ncurc) | ❌ |
Run npm install | Manual | ✅ (-u && install) | ✅ |
| Changelog links | ❌ | ✅ | ✅ |
| TypeScript | ✅ | ✅ | ❌ |
taze
taze — modern dependency checker:
CLI usage
# Check for updates:
npx taze
# Output:
# 2 dependencies updated
# vue 3.4.0 → 3.5.0 (minor)
# typescript 5.4.0 → 5.6.0 (minor)
# 1 devDependency updated
# vitest 2.0.0 → 2.1.0 (minor)
# Write changes to package.json:
npx taze -w
# Interactive mode — select which to update:
npx taze -I
# Filter by update type:
npx taze major # Only show major updates
npx taze minor # Only show minor updates
npx taze patch # Only show patch updates
Monorepo support
# Check all workspace packages:
npx taze -r
# Output:
# packages/app
# vue 3.4.0 → 3.5.0
# pinia 2.1.0 → 2.2.0
#
# packages/ui
# vue 3.4.0 → 3.5.0
# radix-vue 1.8.0 → 1.9.0
#
# packages/utils
# (all up to date)
# Write all workspace updates:
npx taze -r -w
# Interactive monorepo:
npx taze -r -I
Interactive mode
npx taze -I
# Interactive TUI:
# ┌ Select packages to update
# │
# │ ◻ vue 3.4.0 → 3.5.0 (minor)
# │ ◻ typescript 5.4.0 → 5.6.0 (minor)
# │ ◻ vitest 2.0.0 → 2.1.0 (minor)
# │ ◼ eslint 8.50.0 → 9.0.0 (major)
# │
# └ Space to toggle, Enter to confirm
Configuration
// taze.config.ts
import { defineConfig } from "taze"
export default defineConfig({
// Exclude specific packages:
exclude: [
"eslint", // Wait for ecosystem to catch up
"typescript", // Pin to specific version
],
// Package manager:
packageMode: {
"vue": "minor", // Only allow minor updates
"typescript": "patch", // Only allow patches
"/eslint/": "latest", // Regex pattern
},
// Monorepo:
recursive: true,
// Write mode:
write: false,
// Include:
depFields: {
dependencies: true,
devDependencies: true,
peerDependencies: false,
},
})
npm-check-updates (ncu)
npm-check-updates — the standard updater:
CLI usage
# Check for updates (doesn't modify anything):
npx ncu
# Output:
# Checking /Users/royce/project/package.json
# [====================] 15/15 100%
#
# vue ^3.4.0 → ^3.5.0
# typescript ~5.4.0 → ~5.6.0
# vitest ^2.0.0 → ^2.1.0
# eslint ^8.50.0 → ^9.0.0
#
# Run ncu -u to upgrade package.json
# Update package.json:
npx ncu -u
# Update and install:
npx ncu -u && npm install
Filtering
# Filter by package name:
npx ncu -f vue,typescript
npx ncu -f "/eslint/" # Regex
# Exclude packages:
npx ncu -x eslint,typescript
# Filter by update type:
npx ncu --target minor # Only minor updates
npx ncu --target patch # Only patches
npx ncu --target newest # Absolute newest (ignore ranges)
npx ncu --target greatest # Greatest version matching range
npx ncu --target semver # Respect semver ranges
# Filter by dependency type:
npx ncu --dep dev # Only devDependencies
npx ncu --dep prod # Only dependencies
npx ncu --dep dev,prod # Both
Interactive mode
npx ncu -i
# Interactive:
# ? Choose which packages to update
# ◯ vue ^3.4.0 → ^3.5.0 (minor)
# ◯ typescript ~5.4.0 → ~5.6.0 (minor)
# ◯ vitest ^2.0.0 → ^2.1.0 (minor)
# ◯ eslint ^8.50.0 → ^9.0.0 (MAJOR)
# Group by update type:
npx ncu -i --format group
CI integration
# Check if any updates available (exits with code 1 if outdated):
npx ncu --errorLevel 2
# Output as JSON:
npx ncu --jsonUpgraded
# → { "vue": "^3.5.0", "typescript": "~5.6.0" }
# Doctor mode — test each update:
npx ncu --doctor -u
# Updates one package at a time, runs tests after each
# Reverts if tests fail
# Peer dependencies:
npx ncu --peer
Configuration
// .ncurc.json
{
"upgrade": false,
"target": "minor",
"reject": ["eslint", "typescript"],
"dep": "dev,prod",
"format": ["group"],
"packageManager": "pnpm"
}
npm-check
npm-check — interactive dependency review:
CLI usage
# Check for updates with color-coded output:
npx npm-check
# Output:
# ❤️ vue MINOR 3.4.0 → 3.5.0
# ❤️ vitest MINOR 2.0.0 → 2.1.0
# ⚠️ eslint MAJOR 8.50.0 → 9.0.0
# 🔲 old-lib UNUSED? not imported anywhere
# Interactive update:
npx npm-check -u
# Skip unused check:
npx npm-check -s
Interactive update
npx npm-check -u
# Interactive TUI:
# ? Choose which packages to update.
#
# Minor Update New backwards-compatible features.
# ❯ ◯ vue 3.4.0 → 3.5.0 https://vuejs.org
# ◯ vitest 2.0.0 → 2.1.0 https://vitest.dev
#
# Major Update Potentially breaking API changes.
# ◯ eslint 8.50.0 → 9.0.0 https://eslint.org
#
# Non-Semver Versions less than 1.0.0
# ◯ beta-pkg 0.9.0 → 0.10.0
Unused dependency detection
npx npm-check
# Detects potentially unused packages:
# 🔲 lodash UNUSED? Could not find import or require
# 🔲 moment UNUSED? Could not find import or require
#
# Note: May have false positives for:
# - Config-only packages (eslint plugins)
# - Peer dependencies
# - Dynamically imported packages
Global packages
# Check global packages:
npx npm-check -g
# Update global packages interactively:
npx npm-check -g -u
Understanding Semver Update Strategies
The three tools differ not just in UX but in their philosophy around which updates to surface and apply. Understanding the semver update types helps you configure each tool correctly for your team's risk tolerance.
Patch updates (1.2.3 → 1.2.4) are bug fixes within the same minor version. By semver convention, these should be safe to apply automatically — no new features, no breaking changes. In practice, most well-maintained packages honor this, but exceptions exist (particularly in packages that treat security fixes as patch updates when they technically change behavior).
Minor updates (1.2.x → 1.3.0) add new functionality in a backward-compatible way. Generally safe to apply, but libraries that are still pre-1.0 treat minor versions differently — a 0.x → 0.y bump may contain breaking changes. All three tools let you filter to only minor updates with npx taze minor, npx ncu --target minor, and equivalent npm-check options.
Major updates (1.x → 2.0) are the risky ones. They explicitly signal breaking API changes. React 18→19, ESLint 8→9, TypeScript 4→5 — each of these required varying amounts of migration work. The right strategy for major updates is usually to tackle them one at a time, run your test suite after each, and read the migration guide rather than bulk-applying all majors at once.
taze's approach: taze defaults to showing all update types but lets you scope to patch, minor, or major as a positional argument. The packageMode config lets you set per-package policies — for example, pin eslint to only patch updates while allowing vitest to float to latest.
ncu's approach: ncu defaults to showing all updates that exceed the current range. The --target flag controls the semver level: patch, minor, latest, newest, greatest, and semver. The --doctor flag is ncu's unique feature for major upgrades: it updates one package at a time, runs npm test after each, and reverts if the tests fail. This makes aggressive upgrades safer by catching regressions immediately.
npm-check's approach: npm-check categorizes updates visually — minor updates in green, major updates in yellow — and shows the package's homepage URL so you can read the changelog before updating. This human-review-first philosophy suits teams that prefer deliberate updates over automated bulk changes.
The Dependency Hygiene Problem
All three tools solve a real maintenance burden: left unattended, a project's dependencies will gradually fall behind until upgrading becomes a multi-week migration project rather than a routine task. The Node.js ecosystem moves fast — popular packages like React, Vite, TypeScript, and ESLint release major versions every 12-18 months, and minor versions far more frequently.
The compounding problem is transitive dependencies. Your direct dependencies have their own dependencies, which have their own. An outdated top-level dependency can drag along vulnerable transitive dependencies that are patched in newer versions. Tools like npm audit surface these but won't fix them — that requires updating the parent package. This is one reason regular dependency updates (rather than emergency security patches) are good practice.
Regular small updates are dramatically easier than infrequent large updates. A team that updates dependencies weekly rarely encounters breaking changes — they catch them one at a time. A team that defers updates for six months accumulates a backlog of overlapping breaking changes that interact in unexpected ways. All three tools support building this habit: taze with its clean monorepo-aware output, ncu with its CI exit codes that enforce freshness, npm-check with its interactive review workflow.
When dependency updates break things: The ncu --doctor mode is unique in testing each update individually. For projects where you can't easily determine which package caused a test failure, doctor mode bisects the problem automatically. No equivalent exists in taze or npm-check — both assume you'll run your test suite manually after applying updates.
Peer dependency complexity: npm 7+ installs peer dependencies automatically, which can create conflicts when updating packages that share peers. All three tools will surface peer dependency warnings when present, but none automatically resolves conflicts — that still requires human judgment about which package's peer requirements take precedence.
Keeping lock files in sync
One nuance all three tools share: they update package.json version ranges but don't update the lock file. You must run npm install (or pnpm install / yarn install) separately to resolve the new ranges and write an updated pnpm-lock.yaml or package-lock.json. ncu streamlines this with -u && npm install as a common pattern. taze and npm-check require the install step as an explicit follow-up. Committing updated version ranges without an updated lock file creates a situation where the installed versions on CI and in local development may diverge — always commit both together.
For teams using pnpm, the --frozen-lockfile flag on CI (and --prefer-frozen-lockfile for local) catches this: if the lock file is out of sync with package.json, the install fails loudly rather than silently upgrading. This is the correct safety check to pair with any dependency update workflow.
Lock file security considerations
Dependency updates are also a security surface. The supply chain attack vector — malicious packages published with names similar to popular packages, or compromised maintainer accounts pushing malicious versions — has become a real threat. Regular, intentional updates (with diff review of changed packages) are better than automated updates that silently pull in new transitive dependencies. All three tools help you understand what's changing; the human review step remains essential for security-sensitive projects.
For high-security environments, npm-check-updates with --jsonUpgraded can feed a custom review pipeline that checks changed packages against known-good registries or internal allow-lists before writing changes to package.json. The JSON output makes it straightforward to diff the current and proposed package sets in a CI gate before any changes land in the repository.
Feature Comparison
| Feature | taze | npm-check-updates | npm-check |
|---|---|---|---|
| Check outdated | ✅ | ✅ | ✅ |
| Update package.json | ✅ (-w) | ✅ (-u) | ✅ (-u) |
| Interactive mode | ✅ (-I) | ✅ (-i) | ✅ (-u) |
| Monorepo/workspaces | ✅ (-r) | ✅ (--workspaces) | ❌ |
| Unused detection | ❌ | ❌ | ✅ |
| Doctor mode | ❌ | ✅ | ❌ |
| JSON output | ❌ | ✅ | ❌ |
| Regex filtering | ✅ | ✅ | ❌ |
| Config file | ✅ (taze.config.ts) | ✅ (.ncurc.json) | ❌ |
| Per-package mode | ✅ (packageMode) | ✅ (target) | ❌ |
| CI exit code | ❌ | ✅ (errorLevel) | ❌ |
| TypeScript config | ✅ | ❌ (JSON) | ❌ |
| Weekly downloads | ~200K | ~2M | ~500K |
Monorepo Workflows
Dependency management in monorepos is different from single-package repos. You're often updating the same package in 10+ package.json files and need to keep versions in sync.
taze with --recursive:
# Check all packages in a monorepo:
npx taze --recursive
# Update all packages to latest major:
npx taze major --recursive --write
# Output: grouped by package, shows all workspace locations
# react: 18.3.0 → 19.0.0 (×3 workspaces)
# typescript: 5.3.0 → 5.8.0 (×8 workspaces)
taze was designed with monorepos in mind — it understands workspace protocols and groups updates by package name across workspaces.
ncu in workspaces:
# npm-check-updates workspace support:
npx ncu --workspaces # Run in all workspaces
npx ncu --workspace apps/web # Target specific workspace
npx ncu -u --workspaces && npm install # Update and reinstall
ncu added workspace support but the experience is less polished than taze for large monorepos. It works reliably but doesn't group cross-workspace updates.
npm-check: No monorepo support. One package at a time.
For monorepos (Turborepo, Nx, pnpm workspaces), taze is the clear choice — it was built for this workflow and the unified cross-workspace output alone saves significant time during routine maintenance.
CI/CD Integration for Automated Dependency Updates
Manual npx taze runs are fine for one-off audits. Production teams usually automate dependency updates through one of:
1. Renovate Bot (recommended): Not a CLI tool but the most automated solution. Renovate opens PRs for dependency updates automatically, groups related packages, respects semver bounds, and can auto-merge patch updates. Works with any of these CLI tools as a fallback but largely replaces the manual workflow.
2. GitHub Actions with taze:
# .github/workflows/deps-check.yml
name: Dependency Check
on:
schedule:
- cron: '0 9 * * 1' # Every Monday 9am
workflow_dispatch:
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20' }
- run: npm ci
- run: npx taze --recursive --output json > deps-report.json
- uses: actions/upload-artifact@v4
with:
name: deps-report
path: deps-report.json
3. ncu with automatic PR creation:
# Run ncu, write changes, create a branch, open PR:
npx ncu -u
git checkout -b chore/dependency-updates-$(date +%Y-%m-%d)
git add package.json
git commit -m "chore: update dependencies"
gh pr create --title "chore: weekly dependency updates" --body "Auto-generated"
For most teams: use Renovate for automation, and taze or ncu for manual audits when Renovate's PR backlog gets overwhelming.
When to Use Each
Use taze if:
- Working with monorepos (pnpm workspaces, npm workspaces)
- Want a modern interactive TUI
- Need per-package version mode control
- Prefer TypeScript configuration (taze.config.ts)
Use npm-check-updates if:
- Need CI integration (exit codes, JSON output)
- Want doctor mode (test each update individually)
- Need the most filtering options (regex, semver targets)
- Building automated update pipelines
Use npm-check if:
- Want to find unused dependencies
- Prefer a visual, color-coded overview
- Need interactive updates with package descriptions
- Want to audit global packages
Migration Guide
Setting up an automated update workflow with npm-check-updates
For CI-enforced dependency freshness, npm-check-updates provides the best exit code support:
# package.json scripts
{
"scripts": {
"deps:check": "ncu --errorLevel 2",
"deps:update": "ncu -u && pnpm install"
}
}
# GitHub Actions — weekly dependency check
# .github/workflows/deps.yml
name: Dependency Check
on:
schedule:
- cron: "0 9 * * 1" # every Monday at 9am
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npx npm-check-updates --errorLevel 2
Migrating from npm-check to taze for monorepos
npm-check lacks workspace support. Taze's -r flag recursively processes all package.json files in a monorepo:
# npm-check (per-package, no workspace awareness)
cd packages/api && npx npm-check -u
cd packages/web && npx npm-check -u
# taze (workspace-aware, one command)
npx taze -r -I # recursive, interactive
# Shows all packages across workspaces in a unified TUI
# Updates root + all workspace packages in one pass
Community Adoption in 2026
npm-check-updates is the clear download leader at approximately 2 million weekly downloads, driven by its long history (first released 2012), comprehensive documentation, and CI-friendly exit codes. The --doctor mode — which updates packages one at a time and runs your test suite after each, reverting failures — is unique among these tools and valuable for large upgrades.
npm-check reaches around 500,000 weekly downloads. Its key differentiator is unused dependency detection, a feature neither taze nor ncu provide. For JavaScript-only projects without monorepo needs, its color-coded interactive TUI remains the most visually intuitive of the three. However, its lack of maintenance activity (last major update 2019) is a concern for new projects.
taze sits at around 200,000 weekly downloads but is growing rapidly through the UnJS ecosystem. Developed by Anthony Fu (Vite core team), it is the dependency updater of choice in projects like Nuxt, VueUse, and Vitest. Its TypeScript-first configuration file and first-class monorepo support make it the natural choice for modern pnpm workspace setups.
Methodology
Download data from npm registry (weekly average, February 2026). Feature comparison based on taze v0.16.x, npm-check-updates v17.x, and npm-check v6.x.
Compare dependency management and developer tooling on PkgPulse →
See also: patch-package vs pnpm patch vs yarn patch and pkg-types vs read-pkg vs read-package-up, archiver vs adm-zip vs JSZip (2026).