npm-check, npm-check-updates, and syncpack are essential utilities for maintaining healthy dependency trees in Node.js and frontend projects. npm-check provides an interactive interface to audit outdated, unused, and missing packages. npm-check-updates focuses on programmatically updating version specifications in package.json to the latest available versions. syncpack specializes in keeping dependency versions consistent across multiple package.json files, making it ideal for monorepos. Together, they cover the lifecycle of dependency auditing, updating, and synchronization.
Keeping dependencies up to date and consistent is one of the most critical maintenance tasks in modern JavaScript development. Outdated packages introduce security risks, while inconsistent versions across a monorepo can cause subtle bugs and build failures. npm-check, npm-check-updates, and syncpack all address dependency health, but they solve different parts of the problem. Let's compare how they handle auditing, updating, and synchronization.
npm-check is designed for human interaction. It scans your project and launches a terminal-based UI where you can select which packages to update or remove. It also detects unused dependencies, which the other tools do not focus on.
# npm-check: Interactive audit
npx npm-check
# Opens a UI to select updates, remove unused deps, etc.
npm-check-updates (often aliased as ncu) is designed for scripts and automation. It prints a list of outdated packages and can modify package.json directly without asking for confirmation. It does not detect unused packages.
# npm-check-updates: Check versions
npx npm-check-updates
# Prints outdated dependencies to stdout
# Update package.json
npx npm-check-updates -u
# Modifies package.json with latest versions
syncpack focuses on consistency rather than freshness. It audits whether the same package is used at different versions across multiple package.json files in a workspace. It does not check against the npm registry for newer versions by default.
# syncpack: Check for mismatches
npx syncpack list-mismatches
# Lists packages that have different versions across files
npm-check lets you pick specific updates via a checkbox interface. This is safe for manual reviews but impossible to automate in a CI pipeline.
# npm-check: Selective update via UI
npx npm-check --update
# User navigates UI to choose specific packages to update
npm-check-updates supports granular control via CLI flags. You can update only major, minor, or patch versions, or target specific packages. This makes it suitable for automated workflows where you might want to avoid breaking major version changes.
# npm-check-updates: Update minor/patch only
npx npm-check-updates -t minor -u
# Update specific package
npx npm-check-updates -u --filter lodash
syncpack updates versions to make them match each other, not necessarily to make them "latest." You can configure it to align all versions to the highest found in the workspace or to a specific version rule.
# syncpack: Fix mismatches
npx syncpack fix-mismatches
# Aligns versions across package.json files based on config
npm-check generally operates on a single package.json at a time. While you can run it in different directories, it does not inherently understand workspace relationships or hoisting strategies.
# npm-check: Run in specific directory
cd packages/admin && npx npm-check
npm-check-updates can handle multiple files using the --workspace flag or by targeting specific paths. It is aware of npm workspaces and can update root and child manifests in one go.
# npm-check-updates: Workspace support
npx npm-check-updates --workspace
# Updates dependencies across all workspace packages
syncpack is built specifically for monorepos. Its core value proposition is reading multiple package.json files (including pnpm workspaces, lerna, or npm workspaces) and treating them as a single system for dependency versioning.
# syncpack: Config for multiple sources
# .syncpackrc.json
{
"source": [
"package.json",
"packages/*/package.json"
]
}
npm-check has limited configuration options, mostly focused on ignoring specific packages or changing the update mode. It is not designed to be configured via a shared config file for team enforcement.
# npm-check: Ignore specific packages
npx npm-check --ignore-packages eslint
npm-check-updates supports a .ncurc.json configuration file. This allows teams to standardize update behavior, such as defaulting to minor updates or ignoring specific dependencies across the entire organization.
// .ncurc.json for npm-check-updates
{
"reject": ["webpack"],
"target": "minor"
}
syncpack relies heavily on a configuration file (.syncpackrc.json or similar) to define rules. You can enforce that dev dependencies match across packages, or that specific critical libraries (like React) must always use the exact same version everywhere.
// .syncpackrc.json for syncpack
{
"dependencyTypes": ["prod", "dev"],
"semverRange": ""
}
npm-check is unique in its ability to detect unused dependencies. It analyzes your source code to see if an imported package is actually used. It also checks for missing dependencies that are imported but not listed in package.json.
# npm-check: Check unused and missing
npx npm-check --unused --missing
# Reports dependencies installed but not imported
npm-check-updates does not analyze source code. It only compares version strings in package.json against the npm registry. It will not tell you if a dependency is dead weight.
# npm-check-updates: No unused detection
npx npm-check-updates
# Only shows version discrepancies
syncpack also does not analyze source code usage. It focuses strictly on the metadata within package.json files. It can identify dependencies listed in the wrong section (e.g., prod dep in dev), but not if they are unused in code.
# syncpack: List dependencies
npx syncpack list
# Shows dependencies categorized by type, not usage
| Feature | npm-check | npm-check-updates | syncpack |
|---|---|---|---|
| Primary Goal | Interactive Audit | Version Updates | Version Consistency |
| Interface | Terminal UI (Interactive) | CLI / Config | CLI / Config |
| CI/CD Ready | β No (Interactive) | β Yes | β Yes |
| Unused Deps | β Detects unused | β No | β No |
| Monorepo | β οΈ Manual per-folder | β Workspace aware | β Built for monorepos |
| Config File | β οΈ Limited | β
.ncurc.json | β
.syncpackrc.json |
| Update Logic | Selective (Manual) | Registry Latest | Cross-File Match |
You inherited a project with bloated node_modules. You need to find what is actually used.
npm-checknpx npm-check --unused
# Review and uninstall unused packages via UI
Your team wants a GitHub Action that opens a PR whenever new dependency versions are available.
npm-check-updatespackage.json for commit.# In GitHub Action
npx npm-check-updates -u --target minor
npm install
# Commit changes
In a monorepo with 20 packages, you need to ensure every package uses the exact same version of React to avoid hooks errors.
syncpack# In CI pipeline
npx syncpack list-mismatches
# Fails build if React versions differ between packages
npm-check in CI. It requires user input and will hang your pipeline.npm-check-updates for code analysis. It won't tell you if you can safely remove a dependency.syncpack for single-package repos. It adds complexity without benefit if you only have one package.json.Think about your workflow stage:
npm-check locally to prune unused dependencies and audit health interactively.npm-check-updates to keep versions fresh automatically via scripts and bots.syncpack to enforce rules and prevent version drift across multiple packages.Final Thought: These tools are complementary, not mutually exclusive. A mature engineering team often uses syncpack to enforce consistency, npm-check-updates to automate updates, and npm-check occasionally for manual housekeeping.
Choose npm-check if you want an interactive, visual audit of your project's dependencies directly in the terminal. It is best suited for individual developers who need to quickly identify unused, missing, or outdated packages in a single repository without writing scripts. Avoid it for CI/CD pipelines as it is designed for manual interaction rather than automation.
Choose npm-check-updates if your primary goal is to automate version updates in package.json files. It is the industry standard for CI/CD workflows where you need to check for newer versions and update version strings non-interactively. It is ideal for teams that want to keep dependencies fresh via automated pull requests or scheduled scripts.
Choose syncpack if you are managing a monorepo or a project with multiple package.json files that need to stay in sync. It excels at enforcing version consistency across packages and organizing dependencies into specific groups (e.g., separating dev dependencies from production). It is the right tool for architectural governance in complex workspace structures.
Check for outdated, incorrect, and unused dependencies.
-g.-u.import from syntax.npm@3, so dependencies go where you expect them.private: true in their package.json.npm@2 and npm@3, as well as newer alternative installers like ied and pnpm.This is the easiest way to use npm-check.
$ npm install -g npm-check
$ npm-check
The result should look like the screenshot, or something nice when your packages are all up-to-date and in use.
When updates are required it will return a non-zero response code that you can use in your CI tools.
Usage
$ npm-check <path> <options>
Path
Where to check. Defaults to current directory. Use -g for checking global modules.
Options
-u, --update Interactive update.
-y, --update-all Uninteractive update. Apply all updates without prompting.
-g, --global Look at global modules.
-s, --skip-unused Skip check for unused packages.
-p, --production Skip devDependencies.
-d, --dev-only Look at devDependencies only (skip dependencies).
-i, --ignore Ignore dependencies based on succeeding glob.
-E, --save-exact Save exact version (x.y.z) instead of caret (^x.y.z) in package.json.
--specials List of depcheck specials to include in check for unused dependencies.
--no-color Force or disable color output.
--no-emoji Remove emoji support. No emoji in default in CI environments.
--debug Show debug output. Throw in a gist when creating issues on github.
Examples
$ npm-check # See what can be updated, what isn't being used.
$ npm-check ../foo # Check another path.
$ npm-check -gu # Update globally installed modules by picking which ones to upgrade.

-u, --updateShow an interactive UI for choosing which modules to update.
Automatically updates versions referenced in the package.json.
Based on recommendations from the npm team, npm-check only updates using npm install, not npm update.
To avoid using more than one version of npm in one directory, npm-check will automatically install updated modules
using the version of npm installed globally.
Set environment variable NPM_CHECK_INSTALLER to the name of the installer you wish to use.
NPM_CHECK_INSTALLER=pnpm npm-check -u
## pnpm install --save-dev foo@version --color=always
You can also use this for dry-run testing:
NPM_CHECK_INSTALLER=echo npm-check -u
-y, --update-allUpdates your dependencies like --update, just without any prompt. This is especially useful if you want to automate your dependency updates with npm-check.
-g, --globalCheck the versions of your globally installed packages.
If the value of process.env.NODE_PATH is set, it will override the default path of global node_modules returned by package global-modules.
Tip: Use npm-check -u -g to do a safe interactive update of global modules, including npm itself.
-s, --skip-unusedBy default npm-check will let you know if any of your modules are not being used by looking at require statements
in your code.
This option will skip that check.
This is enabled by default when using global or update.
-p, --productionBy default npm-check will look at packages listed as dependencies and devDependencies.
This option will let it ignore outdated and unused checks for packages listed as devDependencies.
-d, --dev-onlyIgnore dependencies and only check devDependencies.
This option will let it ignore outdated and unused checks for packages listed as dependencies.
-i, --ignoreIgnore dependencies that match specified glob.
$ npm-check -i babel-* will ignore all dependencies starting with 'babel-'.
-E, --save-exactInstall packages using --save-exact, meaning exact versions will be saved in package.json.
Applies to both dependencies and devDependencies.
--specialsCheck special (e.g. config) files when looking for unused dependencies.
$ npm-check --specials=bin,webpack will look in the scripts section of package.json and in webpack config.
See https://github.com/depcheck/depcheck#special for more information.
--color, --no-colorEnable or disable color support.
By default npm-check uses colors if they are available.
--emoji, --no-emojiEnable or disable emoji support. Useful for terminals that don't support them. Automatically disabled in CI servers.
--spinner, --no-spinnerEnable or disable the spinner. Useful for terminals that don't support them. Automatically disabled in CI servers.
The API is here in case you want to wrap this with your CI toolset.
const npmCheck = require('npm-check');
npmCheck(options)
.then(currentState => console.log(currentState.get('packages')));
updatefalseglobalfalsecwd is automatically set with this option.skipUnusedfalseignoreDevdevDependencies.--production on the command line to match npm.falsedevOnlydependencies and only check devDependencies.falseignore[]saveExactx.y.z instead of semver range ^x.y.z.falsedebugfalsecwdnpm-check checks.process.cwd()specialsdepcheck special parsers to include.''currentStateThe result of the promise is a currentState object, look in state.js to see how it works.
You will probably want currentState.get('packages') to get an array of packages and the state of each of them.
Each item in the array will look like the following:
{
moduleName: 'lodash', // name of the module.
homepage: 'https://lodash.com/', // url to the home page.
regError: undefined, // error communicating with the registry
pkgError: undefined, // error reading the package.json
latest: '4.7.0', // latest according to the registry.
installed: '4.6.1', // version installed
isInstalled: true, // Is it installed?
notInstalled: false, // Is it installed?
packageWanted: '4.7.0', // Requested version from the package.json.
packageJson: '^4.6.1', // Version or range requested in the parent package.json.
devDependency: false, // Is this a devDependency?
usedInScripts: undefined, // Array of `scripts` in package.json that use this module.
mismatch: false, // Does the version installed not match the range in package.json?
semverValid: '4.6.1', // Is the installed version valid semver?
easyUpgrade: true, // Will running just `npm install` upgrade the module?
bump: 'minor', // What kind of bump is required to get the latest, such as patch, minor, major.
unused: false // Is this module used in the code?
},
You will also see this if you use --debug on the command line.
Additional options can be sent to the depcheck process. See depcheck API. Create a .npmcheckrc{.json,.yml,.js} file and set the depcheck options under depcheck property.
For example, to skip packages for unused check, but still want them in the outdated check (so can't use the --ignore option):
# .npmcheckrc
depcheck:
ignoreMatches: ["replace-in-file","snyk","sonarqube-scanner"]
Hi! Thanks for checking out this project! My name is Dylan Greene. When not overwhelmed with my two young kids I enjoy contributing
to the open source community. I'm also a tech lead at Opower.
Here's some of my other Node projects:
| Name | Description | npmΒ Downloads |
|---|---|---|
gruntβnotify | Automatic desktop notifications for Grunt errors and warnings. Supports OS X, Windows, Linux. | |
shortid | Amazingly short non-sequential url-friendly unique id generator. | |
spaceβhogs | Discover surprisingly large directories from the command line. | |
rss | RSS feed generator. Add RSS feeds to any project. Supports enclosures and GeoRSS. | |
gruntβprompt | Interactive prompt for your Grunt config using console checkboxes, text input with filtering, password fields. | |
xml | Fast and simple xml generator. Supports attributes, CDATA, etc. Includes tests and examples. | |
changelog | Command line tool (and Node module) that generates a changelog in color output, markdown, or json for modules in npmjs.org's registry as well as any public github.com repo. | |
gruntβattention | Display attention-grabbing messages in the terminal | |
observatory | Beautiful UI for showing tasks running on the command line. | |
anthology | Module information and stats for any @npmjs user | |
gruntβcat | Echo a file to the terminal. Works with text, figlets, ascii art, and full-color ansi. |
This list was generated using anthology.
Copyright (c) 2016 Dylan Greene, contributors.
Released under the MIT license.
Screenshots are CC BY-SA (Attribution-ShareAlike).