JavaScript Package Managers

Packages are pieces of code that you can share and reuse like basic components, libraries or frameworks. These packages are versioned and installed based on semantic versioning, your applications can use these packages as dependencies, and each package may or may not depend on other packages.

Package managers are tools that help you manage packages as dependencies and might also provide a global package registry. They work based on manifest files that keep track application metadata and needed dependencies, lock files to offer deterministic installs.

In the Node ecosystem, dependencies get placed within a node_modules directory in your project. The install process starts with resolving dependencies by making requests to the registry and recursively looking up each dependency, then fetching the package tarballs if needed, and finally linking everything together.

npm is the most popular JavaScript package manager; it consists a website to discover packages, a CLI to interact with packages in terminal, and a global registry to share both private and pubic packages.

yarn is a JavaScript package manager released by Facebook in 2016, compatible with the npm registry; it focuses on building a CLI client that is super fast, secure, and deterministic.

pnpm uses hard links and symlinks to save one version of a module only ever once on a disk. When using npm or Yarn for example, if you have 100 projects using the same version of lodash, you will have 100 copies of lodash on disk. With pnpm, lodash will be saved in a single place on the disk and a hard link will put it into the node_modules where it should be installed.

bower is a package manager optimized for frontend; it can manage components that contain HTML, CSS, JavaScript, fonts or even image files. It keeps track packages in bower.json and puts installed packages in bower_components folder. It was created at the time npm only supported node packages, now fading away when both npm and yarn can support both node and browser packages with little help from module bundlers like Webpack or Browserify.

Those package managers may have different set of features but commonly the are created to solve following problems:

  • Working with file archivers to extract package archives
  • Ensuring the integrity and authenticity of the package by verifying their digital certificates and checksums
  • Looking up, downloading, installing, or updating existing software from a software repository or app store
  • Grouping packages by function to reduce user confusion
  • Managing dependencies to ensure a package is installed with all packages it requires, thus avoiding “dependency hell”

Support for symbolic links means that workspaces will be trivial to implement, yarn and pnpm have great support for workspaces. npm v7 will have at least the workspaces feature support of yarn, and will set the stage for more advanced workspaces features in v8.

Most package managers follow semantic versioning scheme which has major.minor.patch (major includes incompatible breaking changes, minor includes backwards compatible new features, patch includes backwards compatible bug fix) format, version numbers and the way they change convey meaning about the underlying code and what has been modified from one version to the next.

Package managers also understand semver ranges indicate the currently acceptable version(s) of the package(s) a developer is depending upon in their project, today and in the future.

To resolve packages by name and version, package managers talk to a registry website that implements the CommonJS Package Registry specification for reading package info. is the largest public JavaScript registry, you can also run your own private registry, and you can configure package managers to talk to any one of them.

In terms of choosing one over the other, yarn is famous for its resolution speed but npm has caught up recently and almost very identical to yarn, you can use either one of them with very little difference; bower is fading away while nnpm is trying hard to gain market share.