update-notifier
Notify CLI users of new npm package versions without slowing down startup
Repository Health
Technical Analysis
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.
Used by 4 apps in this directory
byterover-cli
AI Agents · AI Code Assistants
A portable memory layer for AI coding agents — curate structured project knowledge into a version-controlled context tree that syncs across tools, machines, and teammates.
OmniRoute
AI Agents
A free, open-source AI gateway connecting Claude Code, Codex, Cursor, Cline, and Copilot to 237 AI providers (90+ free) through one endpoint, with automatic fallback and token-compression to stretch free-tier limits further.
Pake
Developer Tools
Turn any webpage into a lightweight native desktop app with one command — built on Rust/Tauri instead of Electron, producing installers nearly 20x smaller (typically under 10MB) for macOS, Windows, and Linux.
Plasmic
CMS · Low Code Platforms · No Code Platforms
The open-source visual builder that lets teams design React apps and websites with drag-and-drop while integrating seamlessly with your codebase.