update-notifier

Notify CLI users of new npm package versions without slowing down startup

Library
npm
v7.3.1
1,809stars
BSD-2-Clause

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
56/100Fair
Development Activity36
Maintenance24
Community64
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
66/100Good
Architecture75
Code Quality78
Innovation55
Learning Curve55

update-notifier checks whether a newer version of your npm package is available and shows a friendly, boxed terminal message recommending the upgrade command. It runs the actual registry check in a detached background process so it never blocks or slows down your CLI’s startup, then caches the result to respect a configurable check interval.

Used by npm, Yeoman, AVA, XO, and thousands of other CLI tools, it automatically stays quiet in CI, inside npm/Yarn scripts, and during tests, and gives end users their own opt-out via a config file, an environment variable, or a CLI flag — making it a drop-in way to gently nudge people toward the latest release.

What You Get

  • Non-blocking update check that spawns a detached child process so your CLI’s startup time is unaffected
  • A polished, boxed terminal notification (via boxen) showing the current vs. latest version and the exact install command to run
  • Configurable check interval, custom message templates with placeholders, and automatic suppression in CI, npm/Yarn scripts, and test environments
  • User-level opt-out via a config file, an environment variable, or a CLI flag

Common Use Cases

  • Global CLI tools that want to nudge users to upgrade instead of silently going stale
  • npm-published developer tools (linters, test runners, scaffolding CLIs) that ship frequent releases
  • Any Node.js command-line application that reads its own version from package.json and wants a battle-tested update-check flow instead of hand-rolling one
  • Projects wanting to reduce support burden from users running outdated versions with known bugs

Under The Hood

Architecture The package splits into three small files with a clear separation of concerns: index.js is a thin factory that constructs an UpdateNotifier and immediately calls .check(); update-notifier.js holds the UpdateNotifier class itself, which owns cached state (via configstore), the public notify()/fetchInfo() API, and the decision of whether a check is due; and check.js is a separate, standalone entry point that only ever runs as a detached, unref’ed child process spawned by check(). This split means the common path (reading cached state and deciding whether to render a notification) is fully synchronous and cheap, while the actual network round-trip to the registry happens out-of-process and can keep running even if the parent CLI calls process.exit() immediately after.

Tech Stack A zero-build, ESM-only (type: module) Node package built from small, focused, largely same-author (sindresorhus) dependencies: configstore for persisted JSON state under the XDG config directory, boxen and chalk for the terminal notification box, pupa for message-template placeholders, semver’s diff/gt functions imported individually for minimal footprint, latest-version for the actual registry lookup, and is-npm/is-installed-globally/is-in-ci for environment detection. There is no bundler or transpilation step; the package ships its raw source directly via the exports field.

Code Quality Tests exist and are reasonably thorough for the package’s size — test/notify.js, test/update-notifier.js, and test/fs-error.js use ava with esmock to mock ESM-only dependencies like is-npm, and assert on the actual rendered terminal output via fixture-stdout/strip-ansi. Error handling is deliberate in at least one specific case: the ConfigStore constructor is wrapped in a try/catch specifically to catch EACCES/EPERM permission failures and print a helpful recovery message instead of crashing. There’s no static typing, but the xo linter (an opinionated ESLint wrapper) runs in CI alongside the test suite across two Node versions, and the class uses private fields (#options, #isDisabled) for encapsulation.

What Makes It Unique It isn’t attempting anything algorithmically novel, but its specific engineering choice — running the registry check in a fully detached, unref’ed child process rather than an in-process async call — is the notable design decision: it guarantees the host CLI’s own startup and exit are never measurably delayed, even if the registry is slow or the calling process exits immediately. That fire-a-subprocess-then-read-the-cached-result-next-time pattern is now the de facto standard the wider CLI ecosystem imitates or depends on directly, reflected in its own README claim of 5000+ downstream projects.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search