The recently released npm 7 adds several features requested by developers, e.g. support for workspaces, better support for peer-dependency management, or deterministically reproducible builds. npm 7 is a big release that includes several breaking changes aiming at improving the overall developer experience.
npm 7’s CLI now supports workspaces, i.e. supports managing multiple packages from within a singular top-level, root package. The workspaces implemented by npm are similar to Yarn workspaces and pnpm workspaces. The npm workspace RFC explained:
After sourcing feedback from the community, there are two major implementations/changes required in the npm CLI in order to provide the feature set that would enable better management of nested packages.
- Make the npm CLI workspace-aware.
- Install: in an npm workspaces setup, users expect to be able to install all nested packages and perform the associated lifecycle scripts from the top-level workspace; it should also be aware of workspaces that have a dependency on one another and symlink them appropriately
The package.json
configuration file now supports a workspaces
property that lists a set of paths referencing a workspace in the file system:
{
"name": "workspace-example",
"version": "1.0.0",
"workspaces": {
"packages": [
"packages/*"
]
}
}
The npm CLI will use the new property to look for valid package.json
files at the configured locations and create a list of packages that will be treated as workspaces.
npm install
now installs dependencies across workspaces. The RFC provides the following example of npm install
output:
// Given this package.json structure:
├── package.json { "workspaces": ["dep-a", "dep-b"] }
├── dep-a
│ └── package.json { "dependencies": { "dep-b": "^1.0.0" } }
└── dep-b
└── package.json { "version": "1.3.1" }
$ npm install
// Results in this symlinking structure:
├── node_modules
│ ├── dep-a -> ./dep-a
│ └── dep-b -> ./dep-b
├── dep-a
└── dep-b
npm 7 also automatically installs peer dependencies along with packages that peer-depend on them. Prior to npm 7, developers needed to manage and install their own peer dependencies. npm 6 simply prompted developers to do so by displaying a warning. The corresponding RFC detailed the rationale behind the new behavior:
That warning is often misinterpreted as a problem and reported to package maintainers, who in response, sometimes omit the peer-dependency, treating it as effectively an optional dependency instead, but with no checks on its version range or validity.
Furthermore, since the npm installer is not peer-dependency aware, it can design a tree that causes problems when peer dependencies are present.
This proposed algorithm addresses these problems, making
peerDependencies
a first-class concept and a requirement for package tree validity.
npm 7 additionally ships with a new package-lock format that enables deterministically reproducible builds. In npm v7, the package-lock.json
file contains everything npm will need to fully build the package tree.
npm 7 includes changes that may break some workflows. Running npm install
with npm 7 in a project with an npm-6 lockfile will replace that lockfile with the new format. This default behavior can be avoided with npm install --no-save
. npm 7 will now block package installations if an upstream dependency conflict is present that cannot be automatically resolved.
Developers may install npm 7 by running npm install --global npm
in a shell terminal. To install npm 6, they should run instead npm install --global npm@6
.
For more details on additional features and breaking changes available in npm 7, interested readers can refer to the full release note.
Yarn, open-sourced by Facebook in October 2016, is a package manager compatible with the public npm registry and uses it by default. Yarn strives to provide different client-side experiences, usually focused on performance and determinism compared to the npm client.
pnpm is an npm-compatible package manager for JavaScript that strives to improve performance and disk space usage.
Created in 2010 as an open-source package manager for Node.js, npm grew to host over 1 million packages in the public npm Registry. npm serves over one billion requests for JavaScript packages per day to approximately 11 million developers worldwide.