Yarn, the next package manager for JavaScript
I currently use npm for managing front lib dependencies on my projects. I was previously using Bower, which turned out to be useless and Yarn will probably be the next tool I’m going to use. Here are the main reasons:
It’s easy
Yarn uses exactly the same package.json
file as npm, making it very easy to make the switch.
The dependencies are by default saved in the same node_modules directory. I didn't find any incompatibility, especially since Yarn 0.16 that supports post install scripts.
The only thing to do is to install it with one or two command lines: https://yarnpkg.com/en/docs/install (spoiler: it doesn’t need npm, contrary to Bower that was a package manager that was installed with… an other package manager).
Here are a few commands to compare NPM and Yarn:
- Init a project with a
package.json
file:npm init
(npm)yarn init
(Yarn)
- Require a package:
npm install [package] --save
(npm)yarn add [package]
- That one will be less confusing for newcomers, with the
--save
that could be forgotten and give the impression that "it works on my machine")
- Install all dependencies of the project:
npm install
yarn install
Other commands are documented here.
It is reliable
When updating packages, Yarn generates a lock file that stores all the exact versions of dependencies that have been installed. You got it, just like Composer with its composer.lock
file in the PHP world.
Why having 2 files when it seems like package.json
is enough?
Think about a project having this dependency:
{
dependencies: {
package1: "1.0.0"
}
}
And that package1
has this dependency like this (which may not be a good idea):
{
dependencies: {
package2: "^1.0"
}
}
The first time you install your project, package1
will resolve the dependency of package2
to version 1.2 (which is the latest version at the moment), but a few months later, installing the project again (on the production server for instance) may install version 1.3 of the package2
dependency, which may introduce some bugs or incompatibilities (despite semantic versioning promise).
Hence the importance of a lock file, that keeps exact version numbers of the install.
The yarn.lock
file therefore needs to be commited in your project repository.
It’s fast
Here are some tests with a simple React project with some usual dependencies (Babel and some loaders, Webpack, and a few libraries):
{
"name": "simple-react-app",
"dependencies": {
"material-ui": "^0.15.4",
"react": "^15.3.1",
"react-addons-update": "^15.3.1",
"react-dom": "^15.3.1",
"react-tap-event-plugin": "^1.0.0"
},
"devDependencies": {
"babel-core": "^6.9.1",
"babel-loader": "^6.2.4",
"babel-preset-es2015": "^6.9.0",
"babel-preset-react": "^6.5.0",
"react-hot-loader": "^3.0.0-beta.3",
"webpack": "^1.13.1",
"webpack-dev-server": "^1.14.1"
}
}
First run on fresh install | Second run on a fresh install (with `yarn.lock` file) | |
---|---|---|
NPM install | 64 seconds | 58 seconds |
This is tested with npm 3.10.8 and Yarn 0.16.0.
And just like the Composer package manager in PHP (hey, PHP it not has-been after all!), Yarn keeps packages in cache, so that they can be installed again without needing an internet connection.