This article describes the differences and relationships among NPM, YARN, and PNPM. If you have any questions, please point out.

Three major players in the package manager space:

  1. npm
  2. Yarn
  3. High-performance NPM (PNPM)

In fact, we already implement basically similar functionality in all package managers, so you will most likely decide which package manager to use based on non-functional requirements, such as installation speed, storage consumption, or actual conditions.

Of course, the way you choose to use each package manager will be different, but they all have basically the same concept. Each of these package managers can execute the following commands:

  • Read and write data
  • Batch install or update all dependencies
  • Add, update, and delete dependencies
  • Run the script
  • Publish a package

However, the package manager is different at the bottom. NPM and Yarn traditionally install dependencies in a tiled node_modules folder. (Note the order here, yarn tiled first, before NPM is recursive). But tiling also poses a number of safety issues.

  1. Dependent structure uncertainty.
  2. Flattening algorithm itself is very complex and time-consuming.
  3. Illegal access is still possible in the project
  4. There are packages with declared dependencies

Therefore, PNPM introduced some new concepts in the node_modules folder to store dependencies more efficiently. Yarn Berry goes even further by abandoning node_modules (PnP) mode altogether (more on that in another article).

JavaScript package a brief history of

The first package manager released was NPM, back in January 2010. This establishes the core principle of how package managers work today. But since NPM has been around for over a decade, why is there an alternative? Here are some key reasons why this happens:

  • node_modulesThe dependency resolution algorithm of folder structure is different (nesting & tiling,node_modulesVs. PnP mode)
  • Different ways of dependency promotion (hoisting)
  • lockingDifferent formats (different performance, e.gyarnThe one I wrote myself)
  • Different ways of storing package files on disks (different space efficiency)
  • Multi-package project (akaworkspaces), which affectsmonoreposMaintainability and speed
  • Different requirements for new tools and commands (different extensibility requirements through plug-ins and community tools)
  • Configurability is different from flexibility

Let’s take an in-depth look at the history of how these aspects were identified after the rise of NPM, how Yarn Classic addressed some of these issues, how PNPM expanded on these concepts, and how Yarn Berry, as the successor to Yarn Classic, broke with these traditional concepts and processes.

Pioneer NPM

NPM is the granddaddy of package managers. Many people mistakenly think that NPM is an acronym for “Node Package Manager,” but this is not the case.

Its release constitutes a revolution, as previously project dependencies were manually downloaded and managed. NPM introduces things like files and their metadata fields, storing dependencies in node_modules, custom scripts, public and private packages, and more.

In 2020, GitHub acquired NPM, so in principle NPM is now managed by Microsoft. At the time of this writing, the latest major release is V8, released in October 2021.

Innovator Yarn Classic

In October 2016, Facebook announced with Google and other companies to develop a new package manager (engineering.fb.com/2016/10/11/…). To address the consistency, security, and performance issues at the time of NPM. They named the alternative Yarn.

Yarn has had a significant impact on the package manager world, although it is architeted based on many of the concepts and processes of NPM. Compared to NPM, Yarn parallelizes operations to speed up the installation process, which has been a major pain point in earlier versions of NPM.

Yarn set higher standards for read and write, security, and performance, and invented many concepts (which NPM later improved on), including:

  • monoreposupport
  • Cache installation
  • Offline download
  • File lock (Locking)

Yarn V1 enters maintenance mode in 2020. Since then, the V1.x series has been considered an older version and renamed Yarn Classic. Its successor Yarn V2 (Berry) is now the more active development branch.

More efficientpnpm

Version 1 of PNPM was released by Zoltan Kochan in 2017. It is an alternative to NPM, so if you have an NPM project, you can use PNPM right away!

The main reason for creating PNPM is that NPM and Yarn are very redundant for dependency storage structures used across projects. Although Yarn Classic has a speed advantage over NPM, it uses the same dependency resolution method, which is not possible for PNPM: NPM and Yarn Classic use a reactive tiling of their node_modules.

Instead of optimizing the previous structure, PNPM introduces another dependency resolution strategy: a storage structure for content addressing. The node_modules folder generated by this method actually depends on the ~/. Pnpm-store/directory stored globally on the home folder. Each version’s dependencies are physically stored once in that directory folder, forming a single source address to save considerable disk space.

The node_modules structure is a nested structure that creates dependencies using Symlinks (where every file/package in a folder is stored by hard link) as illustrated in the figure below in the official documentation. (Pit to be filled: soft and hard links)

2021 reportIn the visiblepnpmInfluence: because they are inContent addressable storageIn terms of innovation that competitors want to adoptpnpmFor exampleThe structure of symbolic linksAnd package efficient disk management.

Yarn (V2, Berry), wheel reinvented with Plug’n’Play

Yarn 2 was released in January 2020 and was billed as a major upgrade to original Yarn. The Yarn team calls it Yarn Berry to make it more obvious that it is essentially a new package manager with a new code base and a new principle specification.

The main innovation of Yarn Berry is its plug and play (PnP) approach, which is used as a strategy to fix node_modules. Instead of generating node_modules, generate a file with a dependency lookup table.pnp.cjs, which handles dependencies more efficiently because it’s a single file rather than a nested folder structure. In addition, each package is stored as a zip file in a folder instead of.yarn/cache/ and takes up less disk space than node_modules.

All of these changes were so rapid that they caused a lot of controversy after their release. Such disruptive and significant changes to PnP require maintainers to update their existing packages for compatibility. Using the new PnP method by default and reverting to node_modules was not initially simple, which led many high-profile developers to skip the consideration and openly criticize Yarn 2.

Since then, the Yarn Berry team has addressed many of the issues in its subsequent versions. To address PnP incompatibilities, the team provided a way to easily change the default mode of operation. With the node_modules plug-in, switching back to the traditional node_modules method requires only one line of configuration.

In addition, over time, the JavaScript ecosystem has provided more and more support for PnP, and as you can see in this compatibility table, some large projects have started to adopt Yarn Berry.

Although Yarn Berry is still young, it is already making an impact on the package manager space — PNPM adopted the PnP approach in late 2020.

Installation workflow

The package manager must first be installed on each developer’s local and CI/CD systems.

npm

NPM comes with Node.js, so no additional steps are required. In addition to downloading the Node.js installer for your operating system, it has become common practice to use CLI tools to manage software versions. In the context of Node, Node Version Manager (NVM) or Volta has become a very handy utility.

Yarn Classic and Yarn Berry

You can install Yarn 1 in different ways, for example, as an NPM package:.$NPM I -g Yarn

To migrate from Yarn Classic to Yarn Berry, the recommended method is:

  • Install or update Yarn Classic to the latest version

  • Use the command to upgrade to the latest modern version

    yarn set version berry
    Copy the code

However, the recommended way to install Yarn Berry here is through Corepack.

Corepack was created by the developers of Yarn Berry. The plan was originally named Package Manager Manager (PMM) 🀯 and was merged with Node in LTS V16.

With the help of Corepack, because Node contains Yarn Classic, Yarn Berry, and PNPM binaries, you don’t have to install an alternative package manager for NPM “separately.” These shippers allow the user to run Yarn and PNPM commands without explicitly installing them first, and without messing up the Node distribution.

Corepack comes preloaded with Node.js β‰₯ V16.9.0. However, for older Versions of Node, you can use ⬇️

npm installΒ -g corepack
Copy the code

Enable Corepack before using it. This example shows how to activate it in Yarn Berry V3.1.1.

# you need to opt-in first
$ corepack enable
# shim installed but concrete version needs to activated
$Corepack prepare [email protected] - activate
Copy the code

pnpm

You can install PNPM as an NPM package: $NPM I -g PNPM. You can also install PNPM using Corepack:

$Corepack prepare [email protected] - activate
Copy the code

The project structure

In this section, you will see the main characteristics of different package managers at a glance. You can easily find out which files are involved in configuring a particular package manager and which files are generated by the installation steps.

All package managers store all important meta information in the project manifest package.json file. In addition, root-level profiles can be used to set up different private packages or different dependency resolution configurations.

In the installation step, the dependency dependencies are stored in a file structure, such as node_modules, and the locking file is generated. This section does not consider workspace Settings, so all examples show only a single location where dependencies are stored.

npm

Using $NPM install or the shorter $NPM I generates a package-lock.json file and a node_modules folder. Also, configurable files such as.npmrc can be placed in the root directory. See the next section for more information about the locking file.

.β”œ ── β”œβ”€ β”œβ”€ package-lock.json β”œβ”€.β”œ.txtCopy the code

yarn

Running $yarn creates a yarn.lock file and a node_modules folder. Yarnrc files can also be configured as an option, and Yarn Classic also supports.npmrc files. Alternatively, you can use the cache folder. Yarn /cache/ and the latest version of yarn Classic for local storage. Yarn/Releases /.

. β”œ ─ ─ the yarn / β”‚ β”œ ─ ─ cache / β”‚ β”” ─ ─ the releases / β”‚ β”” ─ ─ yarn - 1.22.17. CJS β”œ ─ ─ node_modules / β”œ ─ ─ the yarnrc β”œ ─ ─ package. The json β”” ─ ─ yarn.lockCopy the code

yarn berry: node_modules

Because of this special setup mode, you have to deal with more files and folders in the Yarn Berry project than with other package managers. Some are optional, some are mandatory.

Yarn Berry is no longer supported. NPMRC or. Yarnrc; He needs a.yarnrC.yML. For the traditional workflow of generating the node_modules folder, you must provide the nodeLinker configuration to use either node_modules or PNPM configuration.

# .yarnrc.yml
nodeLinker: node-modules # or pnpm
Copy the code

Running $YARN installs all dependencies in a node_modules folder. A yarn.lock file is generated, which is newer but not compatible with YARN Classic. In addition, a.yarn/cache/ folder is generated for offline installation. This folder is optional and is used to store the version of Yarn Berry used by the project.

. β”œ ─ ─ the yarn / β”‚ β”œ ─ ─ cache / β”‚ β”” ─ ─ the releases / β”‚ β”” ─ ─ yarn - 3.1.1. CJS β”œ ─ ─ node_modules / β”œ ─ ─ the yarnrc. Yml β”œ ─ ─ package. The json β”” ─ ─ yarn.lockCopy the code

yarn berry: pnp

In either strict or loose PnP mode, executing $yarn with.pnp. CJS and yarn.lock produces a.yarn/cache/ and.yarn/unplugged. PnP strict is the default mode. If you want to configure loose mode, you need to enable ⬇️ as follows:

# .yarnrc.yml
nodeLinker: pnp
pnpMode: loose
Copy the code

In a PnP project, the.yarn folder will most likely contain an SDK/folder that provides IDE support in addition to the Releases folder. Depending on your use case,.yarn can contain even more folders.

. β”œ ─ ─ the yarn / β”‚ β”œ ─ ─ cache / β”‚ β”œ ─ ─ the releases / β”‚ β”‚ β”” ─ ─ yarn - 3.1.1. CJS β”‚ β”œ ─ ─ the SDK / β”‚ β”” ─ ─ unplugged / β”œ ─ ─ the PNP. The CJS β”œ ─ ─ .pnp.loader.mJS β”œβ”€.YML β”œβ”€ package.json β”œβ”€.pnp.loader.mJS β”œβ”€.YarnrcCopy the code

pnpm

As with the initial state of an NPM or Yarn Classic project, PNPM requires package.json files. After installing the dependencies with $PNPM I, a node_modules folder is generated, but its structure is completely different because its contents are addressable storage.

PNPM also generates its own lock file, PNP-lock. yml. You can provide additional configuration using the optional.npmrc file.

. β”œ ─ ─ node_modules / β”‚ β”” ─ ─ the PNPM / β”œ ─ ─ the NPMRC β”œ ─ ─ package. The json β”” ─ ─ PNPM - lock. YmlCopy the code

Lock files and dependent stores

As described in the previous section, each package manager creates lock files.

The LOCK file stores exactly the version of each dependency installed by your project for a more predictable and deterministic installation. This lock file is important because dependent versions are likely to use version range declarations (for example, β‰₯ v1.2.5), and the actual installed version may be different if you do not “lock” your version.

Lock files also sometimes store checksums (a hash, AS I recall), which we’ll cover in more detail in the security section.

Locking files has been the main function of NPM since NPM v5+ (package-lock.json). In PNPM, it is pnpm-lock.yaml. In Yarn Berry, yarn.lock appears in the new YAML format.

In the previous section, we saw the traditional approach of installing dependencies in the node_modules folder structure. This is the scheme used by NPM, Yarn Classic and PNPM (where PNPM is more effective than the others).

Yarn Berry works differently in PnP mode. Instead of the node_modules folder, dependencies are stored as zip files as a combination of.yarn/cache/ and.pnp.cjs files.

It’s best to keep these locked files under version control, because every team member installs the same version, so it solves the “work on your machine and mine” problem.

CLI

The following table compares the different CLI commands available in NPM, Yarn Classic, Yarn Berry, and PNPM. This is by no means a complete list, but rather a cheat sheet. This section does not cover workflow-related commands.

NPM and PNPM have a number of AD hoc command and option aliases, which means that commands can have different names, namely $NPM install versus $NPM add. In addition, many command options have abbreviated versions, such as -d instead of –save-dev. In the table, I call all abbreviated versions aliases. With each of these package managers, you can add, update, or remove multiple dependencies.

Dependency Configuration Management

This table covers dependency management commands to install or update all dependencies specified in package.json.

Action npm Yarn Classic Yarn Berry pnpm
install deps in package.json npm install alias: i, add yarn install or yarn like Classic pnpm install alias: i
update deps in package.json acc. semver npm update alias: up, upgrade yarn upgrade yarn semver up (via plugin) pnpm update alias: up
update deps in package.json to latest N/A yarn upgrade –latest yarn up pnpm update –latest alias: -L
update deps acc. semver npm update react yarn upgrade react yarn semver up react pnpm up react
update deps to latest npm update react@latest yarn upgrade react –latest yarn up react pnpm up -L react
update deps interactively N/A yarn upgrade-interactive yarn upgrade-interactive (via plugin) $ pnpm up –interactive alias: -i
add runtime deps npm i react yarn add react like Classic pnpm add react
add dev deps npm i -D babel alias: –save-dev yarn add -D babel alias: –dev like Classic pnpm add -D babel alias: –save-dev
add deps to package.json without semver npm i -E react alias: –save-exact yarn add -E react alias: –exact like Classic pnpm add -E react alias: –save-exact
uninstall deps and remove from package.json npm uninstall react alias: remove, rm, r, un, unlink yarn remove react like Classic pnpm remove react alias: rm, un, uninstall
uninstall deps w/o update of package.json npm uninstall –no-save N/A N/A N/A

Installation configuration Management

The following example shows how to manage packages during development. Terms used in the table:

  • Package: dependency or binary
  • Binary: an implementation tool fromnode_modules/.bin/ or.yarn/cache/ (PnP)

It is important to understand that Yarn Berry only allows us to execute specified binaries in package.json or exposed in bin/ files.

Action npm Yarn Classic Yarn Berry pnpm
install packages globally npm i -g ntl alias: –global yarn global add ntl N/A (global removed) pnpm add –global ntl
update packages globally npm update -g ntl yarn global upgrade ntl N/A pnpm update –global ntl
remove packages globally npm uninstall -g ntl yarn global remove ntl N/A pnpm remove –global ntl
run binaries from terminal npm exec ntl yarn ntl yarn ntl pnpm ntl
run binaries from script ntl ntl ntl ntl
dynamic package execution npx ntl N/A yarn dlx ntl pnpm dlx ntl
add runtime deps npm i react yarn add react like Classic pnpm add react
add dev deps npm i -D babel alias: –save-dev yarn add -D babel alias: –dev like Classic pnpm add -D babel alias: –save-dev
add deps to package.json without semver npm i -E react alias: –save-exact yarn add -E react alias: –exact like Classic pnpm add -E react alias: –save-exact
uninstall deps and remove from package.json npm uninstall react alias: remove, rm, r, un, unlink yarn remove react like Classic pnpm remove react alias: rm, un, uninstall
uninstall deps w/o update of package.json npm uninstall –no-save N/A N/A N/A

Common commands

This table covers some useful built-in commands. If no official command is available, third-party commands can usually be used through the NPM package or the Yarn Berry plug-in.

Action npm Yarn Classic Yarn Berry pnpm
Contract awarding npm publish yarn publish yarn npm publish pnpm publish
list installed deps npm ls alias: list, la, ll yarn list pnpm list alias: ls
list outdated deps npm outdated yarn outdated yarn upgrade-interactive pnpm outdated
print info about deps npm explain ntl alias: why yarn why ntl like Classic pnpm why ntl
init project npm init -y npm init (interactive) alias: –yes yarn init -y yarn init (interactive) alias: –yes yarn init pnpm init -y pnpm init (interactive) alias: –yes
print licenses info N/A (via third-party package) yarn licenses list N/A (or via plugin, other plugin) N/A (via third-party package)
update package manager version N/A (with third-party tools, e.g., nvm) With NPM: yarn policies set-version 1.13.0 With Corepack: YARN set version 3.1.1 N/A (with npm, Corepack)
perform security audit npm audit yarn audit yarn npm audit pnpm audit
add deps to package.json without semver npm i -E react alias: –save-exact yarn add -E react alias: –exact like Classic pnpm add -E react alias: –save-exact
uninstall deps and remove from package.json npm uninstall react alias: remove, rm, r, un, unlink yarn remove react like Classic pnpm remove react alias: rm, un, uninstall
uninstall deps w/o update of package.json npm uninstall –no-save N/A N/A N/A

The configuration file

Configuring the package manager takes place in your package.json and in your proprietary configuration files.

  • Define the exact version to use
  • Use a specific dependency resolution strategy
  • Configure the private registry
  • Tell the package manager where to find itmonorepoWorkspace in

npm

Most of the configuration takes place in the specialized configuration file.npmrc.

If you want to use NPM’s Workspaces feature, you must add workSpaces metadata fields in package.json to tell NPM where to find folders for subprojects or workspaces.


  // ...
  "workspaces": [
    "hooks"."utils"]}Copy the code

Each package manager can use the common NPM registry. You probably want to reuse them without publishing them to the public registry. You can do this in the.npmrc file to configure the registry privately. (Now there are almost all private sources)

# .npmrc
@doppelmutzi:registry=https://gitlab.doppelmutzi.com/api/v4/projects/41/packages/npm/
Copy the code

NPM has a number of configuration options that are best viewed in documentation. \

yarn

You can set yarn workspaces (which must be private packages) in package.json.

{/ /... "private": true, "workspaces": ["workspace-a", "workspace-b"] }Copy the code

Any optional configuration goes into a.yarnrc file. A common configuration option is to set up a yarn-path: it forces each team member to use the specified binary version. Yarn-path points to a folder that contains a particular version of YARN (for example,.yarn/ Releases /). You can use the command to install the uniform Yarn Classic version (classic.yarnpkg.com/en/docs/cli…). .

yarn berry

Configuring Workspaces in Yarn Berry is similar to configuring workspaces in Yarn Classic (package.json). Most Yarn Berry configuration occurs in.yarnrc.yml, and there are a number of configuration options available.

# .yarnrc.yml
yarnPath: . The yarn/releases/yarn - 3.1.1. CJS
Copy the code

Yarn Berry can be extended by importing $> yarn Plugin import

(yarnpkg.com/cli/plugin/…) This command will also update.yarnrc.yml.

# .yarnrc.yml
plugins:
  - path: .yarn/plugins/@yarnpkg/plugin-semver-up.cjs
    spec: "https://raw.githubusercontent.com/tophat/yarn-plugin-semver-up/master/bundles/%40yarnpkg/plugin-semver-up.js"
Copy the code

As described in the history section, dependencies in PnP strict mode can be problematic because of compatibility. There is a typical solution to such PnP problems: package extension configuration policies.

# .yarnrc.yml
packageExtensions:
  "styled-components@*":
    dependencies:
      react-is: "*"
Copy the code

pnpm

PNPM uses the same configuration mechanism as NPM, so you can use.npmrc files. Configuring the private registry also works in the same way as using NPM. Multiple package projects can be supported with the workspace functionality of PNPM. To initialize monorepo, you must specify the location of the package in the pnpm-workshop.yaml file.

# pnpm-workspace.yaml
packages:
  - 'packages/**'
Copy the code

Monorepo

What is a Monorepo

(Here are actually three concepts, single warehouse multi-project, single warehouse single project, multi-warehouse multi-project)

Monorepo is a repository that contains multiple projects called workspace or packages. Keeping everything in one place rather than using multiple repositories is a project organization strategy.

Of course, this introduces additional complexity. Yarn Classic was the first to enable this feature, but now every major package manager provides workspace functionality. This section shows how to configure the workspace with each different package manager.

npm

The NPM team has released the long-awaited NPM Workspace feature in V7. It contains a number of CLI commands to help manage multi-package projects from the root package. Most commands can be used with workspace related options to tell NPM whether it should run for specific, multiple, or all workspaces.

# Installing all dependencies for all workspaces
$ npm i --workspaces.
# run against one package
$ npm run test --workspace=hooks
# run against multiple packages
$ npm run test --workspace=hooks --workspace=utils
# run against all
$ npm run test --workspaces
# ignore all packages missing test
$ npm run test --workspaces --if-present
Copy the code

Tips: Compared to other package managers, NPM V8 does not currently support advanced filtering or parallel execution of multiple workart-specific commands.

yarn

In August 2017, the Yarn team announced monorepo support for workspace functionality. Previously, package managers were only available in multi-package projects for third-party software such as Lerna. This addition to Yarn paves the way for other package managers to do the same.

If you are interested, see how to use Yarn Classic’s Workspace feature with and without Lerna. But this article covers only the commands necessary to help you manage dependencies in your Yarn Classic workspace Settings.

#Install all dependencies for all workspaces
$ yarn 
#Displays the dependency tree
$ yarn workspaces info 
#Another package runs to start
$ yarn workspace awesome - package start
  #Add Webpack to the package
$ yarn workspace awesome - package add - D webpack
  #Add React to all packages
$ yarn add react -W
Copy the code

yarn berry

Yarn Berry has featured workspaces from the beginning, as its implementation is built on the concept of Yarn Classic. In a Reddit comment, Yarn Berry’s lead developers briefly outlined the workspace-oriented features, including:

  • $YARN add –interactive: You can reuse versions from other workspaces when installing packages
  • $YARN UP: Updates packages for all workspaces
  • $YARN Workspaces Focus: Install dependencies for a single workspace only
  • $YARN workspaces foreach: Run the command on all workspaces

Yarn Berry uses a number of protocols available for dependencies or devDependencies fields in package.json files. Among them is the Workspace protocol.

In contrast to the Yarn Classic workspace, Yarn Berry explicitly defines that the dependency must be one of the packages in this Monorepo. Otherwise, if the version does not match, Yarn Berry may try to get its version from the remote registry.

{
  // ...
  "dependencies": {
    "@doppelmutzi/hooks": "workspace:*"."http-server": "14.0.0".// ...}}Copy the code

pnpm

Through the Workspace protocol, PNPM facilitated the Monorepo project similar to Yarn Berry. Many PNPM commands accept options like –recursive (-r) or –filter that are particularly useful in the context of Monorepo. Its native filtering commands are also a nice complement to Lerna.

# prune all workspaces  
pnpm -r exec -- rm -rf node_modules && rm pnpm-lock.yaml  
# run all tests for all workspaces with scope @doppelmutzi
pnpm recursive run test --filter @doppelmutzi/`
Copy the code

Performance & Disk efficiency

Performance is a key part of the selection decision. This section shows benchmarks based on one small and one medium-sized project. Here are some notes about the sample project:

  • Neither set of benchmarks uses workspace functionality
  • The small project specifies 33 dependencies
  • The project specifies 44 dependencies

I measured each of our package manager variants once with three use cases (UC). For a detailed assessment and explanation, see the results of items 1 (P1) and 2 (P2).

  • UC 1: No cache/storage, no locked files, nonenode_modulesor.pnp.cjs
  • UC 2: Cache/storage exists, no locked file, nonode_modules ζˆ– .pnp.cjs
  • UC 3: Cache/storage exists, locked file exists, nonode_modules ζˆ– .pnp.cjs

I use tools gnomon to measure the consumption of installation time (yarn | gnomon). Also I measured the size of the generated file $du -sh node_modules.

Performance results for Project 1
Method NPM v8.1.2 Yarn Classic v1.23.0 PNPM v6.24.4 Yarn Berry PnP loose v3.1.1 Yarn Berry PnP strict v3.1.1 Yarn Berry node_modules v3.1.1 Yarn Berry pnpm v3.1.1
UC 1 86.63 s 108.89 s 43.58 s 31.77 s 30.13 s 56.64 s 60.91 s
UC 2 41.54 s 65.49 s 26.43 s 12.46 s 12.66 s 46.36 s 40.74 s
UC 3 23.59 s 40.35 s 20.32 s 1.61 s 1.36 s 28.72 s 31.89 s
Files and size Package – lock. Json: 1.3 M node_modules: 467 M node_modules: 397M yarn.lock: 504K pnpm-lock.yaml: 412K node_modules: 319M Yarn. lock: 540K Cache: 68M unplugged: 29m.pnp. CJS: 1.6M Yarn. lock: 540K Cache: 68M unplugged: 29M. PNP. CJS: 1.5M node_modules: 395M yarn.lock: 540K cache: 68M node_modules: 374M yarn.lock: 540K cache: 68M
Performance results for Project 2
Method NPM v8.1.2 Yarn Classic v1.23.0 PNPM v6.24.4 Yarn Berry PnP loose v3.1.1 Yarn Berry PnP strict v3.1.1 Yarn Berry node_modules v3.1.1 Yarn Berry pnpm v3.1.1
UC 1 34.91 s 43.26 s 15.6 s 13.92 s 6.44 s 23.62 s 20.09 s
UC 2 7.92 s 33.65 s 8.86 s 7.09 s 5.63 s 15.12 s 14.93 s
UC 3 5.09 s 15.64 s 4.73 s 0.93 s 0.79 s 8.18 s 6.02 s
Files and size package-lock.json: 684K node_modules: 151M yarn.lock: 268K node_modules: 159M pnpm-lock.yaml: 212K node_modules: 141M Pnp.cjs: 1.1m. Pnp.loader. MJS: 8.0K yarn.lock: 292k.yarn: 38M Pnp.cjs: 1.0m.pnP.loader. MJS: 8.0K yarn.lock: 292k.yarn: 38M yarn.lock: 292K node_modules: 164M cache: 34M yarn.lock: 292K node_modules: 156M cache: 34M

security

npm

NPM is a little too lenient in dealing with bad packages and has encountered some security vulnerabilities that directly affect many projects. For example, in version 5.7.0, when you execute the sudo NPM command on a Linux operating system, you can change the ownership of system files, making the operating system unusable.

Another incident, in 2018, involved the theft of Bitcoin. The Node.js package EventStream added malicious dependencies in its version 3.3.6. The malicious package contains an encryption method that attempts to steal Bitcoins from the developer’s machine.

To help address these issues, the new NPM version uses cryptographic algorithms to check the integrity of the packages you install. SHA – 512.

yarn

Yarn Classic and Yarn Berry use checksums to verify the integrity of each package from the start. Yarn also tries to prevent you from retrieving malicious packages that are not declared in package.json: if a mismatch is found, the installation is aborted.

Yarn Berry in PnP mode has no security problems in traditional node_modules mode. Yarn Berry improves command execution security compared to Yarn Classic. You can only execute packages already declared in package.json. This security feature is similar to PNPM, which I describe below.

pnpm

PNPM still uses checksums to verify the integrity of each installed package before executing its code.

As we mentioned above, both NPM and Yarn Classic have security issues due to upgrades. PNPM avoids this situation because its management model does not use promotions; Instead, it generates nested node_modules folders to eliminate the risk of illegal dependent access. This means that the dependencies are declared in.package.json.

As we discussed, this is especially important in monorepo Settings, because promotion algorithms can sometimes lead to dependency uncertainty.

Usage of popular items

npm Yarn Classic Yarn Berry pnpm
Svelte React Jest (with node_modules) Vue 3
Preact Angular Storybook (with node_modules) Browserlist
Express.js Ember Babel (with node_modules) Prisma
Meteor Next.js Redux Toolkit (with node_modules) SvelteKit
Apollo Server Gatsby
Nuxt
Create React App
webpack-cli
Emotion

conclusion

The principles of different package managers do vary widely.

PNPM looks like NPM at first, because their CLI usage is similar, but the management dependencies are very different; PNPM’s approach results in better performance and optimal disk space efficiency. Yarn Classic is still popular, but it is considered legacy software and may be dropped from support in the near future. Yarn Berry PnP is brand new, but people have yet to realize its potential to revolutionize the package manager space once again.

Over the years, many users have asked who uses which package managers, and overall there seems to be particular interest in the maturity and adoption of Yarn Berry PnP.

The purpose of this article is to give you multiple perspectives on which package manager to use for yourself. I want to point out that I do not recommend a specific package manager. It depends on how you weigh different requirements — so you can still choose whatever you like!

Other related articles:

Juejin. Cn/post / 693204…

Juejin. Cn/post / 684490…

Loveky. Making. IO / 2019/02/11 /…

www.raulmelo.dev/blog/replac…