Last modified: May 3, 2017
With the advent of Node.js, npm has quickly become one of the most popular package managers used today. Using npm's central repository, developers can easily publish and reuse code faster than ever before. Even companies like Facebook depend on the npm ecosystem for widely used libraries like React.js.
Despite such popularity, npm does have its problems. Known issues with performance and security have led to the more recent creation of yarn, an improved package manager created by Facebook, Google, Exponent, and Tilde. While yarn is still relatively new, it's proven both more efficient and secure than npm. In this article, we discuss the issues with npm and how yarn improves on such issues.
Yarn was created to address the major issues experienced with npm. These issues are described in detail below:
NPM uses semantic versioning(semvar) to define a versioning schema for dependency management. This essentially means that you can define a range of acceptable versions for any given module or library to use in your project. This gives your dependency tree more flexibility in "choosing" the best versions for your build at any given time.
Using semvar greatly simplifies dependency management but can produce inconsistent results. If developer A runs npm install it may install different versions of the same dependencies used by developer B. This can lead to "works on my machine" issues where the same project will fail for developer A and work for developer B. It also presents security related issues as unspecified dependency versions allow for potentially malicious code to be published and used in development.
By default, npm installs dependencies non-deterministically, meaning that the order in which dependencies are installed could vary from one developer to the next. This also perpetuates the "works on my machine" issue as inconsistencies can arise in local environments.
Whenever you run npm install a series of tasks are performed sequentially. Specifically, npm executes tasks per package and in a specific order. This has proven significantly slower than approaches taken by yarn and other package managers.
Yarn addresses most of these pitfalls experienced with npm. While yarn is compatible with the same npm registry, it allows developers to download dependencies faster and with more consistency.
Yarn uses a deterministic algorithm for downloading dependencies. This allows dependencies to be downloaded in parallel (versus the sequential nature of npm) and is much faster than npm.
Yarn uses a yarn.lock file to specify which versions of which dependencies to use. While npm shrinkwrap allows developers to specify specific versions, it requires extra configuration. Yarn does this by default. This ensures that developers have the same exact dependencies and protects against the "works on my machine" issue.
Yarn uses a global cache to save dependencies to disk. This allows developers to more easily work in offline "sandboxed" environments and is more conducive to continuous integration. In fact, one of the main inspirations for yarn was the need for developers to work without an active network connection.
While yarn is still relatively new, it has proven to be both faster and more secure than npm. It should be noted that you can use yarn interchangeably with npm. You can still push and pull from the same registry and benefit from the rich community that has made npm so popular. Although using npm is still perfectly acceptable, exploring yarn will allow you to use npm with better reliability and performance moving forward.