Alternative Package Managers For Node.js

Amir Muminović

Node.js is a powerful platform used all over the world to build incredible things. In this article I will present the whats and whys of Node.js, the package managers you can choose from, and explain why we continuously choose to work with this technology.

First, let’s take a moment to consider the fact that for the past couple of years JavaScript has been the most popular and fastest growing programming language (based on the research done by Business Insider and StackOverflow)

Node.js is a JavaScript framework which has followed this advance and as a result was the most popular framework in 2018. The BOSS index, which tracks the explosive growth of open source software, has ranked Node.js fourth, trailing behind Linux, Git, and MySQL.

Here are a few other facts confirming Node.js’s popularity:

  • 1 billion downloads
  • 10 million users
  • 800 000 building blocks
  • over 2000 contributors

Companies like IBM, Intel, Google, Microsoft, and Paypal are members of the Node Foundations.

You can use Node.js to create high-performance apps with low latency.

Node apps have found application in enterprise applications, cloud stacks, IoT, mobile websites, robots, API engines and more.

What exactly is Node.js?

Node.js is development platform based on an asynchronous, event-driven, non-blocking IO model. If you are not familiar with most words in the previous sentence, here is a brief explanation:

Synchronous code requires all programming statements to be executed in their right order. If the program needs to work with external services, we have to wait until the information arrives. No work can be done while we are waiting. If there are a lot of I/O operations in the code, the computer will spend most of the time waiting. We can say that I/O is blocking the computer from working at its full potential. That is why it would be great if we could initiate the I/O calls and work on something else while we wait — asynchronously. Once we get the info we need, the program can signal that the event of waiting for data is done. Knowing that event is done, we can perform what we wanted with the data — performing a callback function.

How is it different from other platforms?

In the previous section we outlined that by running code asynchronously we can perform more actions concurrently. Most concurrency models are based on the use of OS threads. It might come as a surprise, but Node.js code execution is single-threaded. The reason behind it is that using threads for networking is inefficient and difficult to use. So how exactly does Node.js do it?

On other platforms, we define the wanted behavior at the beginning by using callbacks. Once we are done, we start a server through a blocking call at the end of the program. The blocking call is necessary for starting the event loop.

Node doesn’t have the blocking Start-The-Event-Loop call. It enters the loop right after executing the input script. The event loop is presented as a part of the runtime construct rather than a library. This design was influenced by Ruby’s Event Machine and Python’s Twisted.

Performance

One of the main benefits of Node.js is the dazzling performance. The following diagrams show just how drastic the performance boost can be:

There are three key factors which allow node apps to perform so well:

1) Node.js is based on the V8 JavaScript engine — developed and highly optimized by Google.

2) Node.js is based on a single-threaded model so the events are lightweight. Other frameworks, which utilize multithreading, suffer from a performance loss because threads themselves are heavyweight.

3) Node.js is container-ready so moving to cloud and microservices architectures is simplified.

Cost Reduction

An annual survey conducted by the Node.js foundation has concluded that 56% of the users reported lower costs by using this platform. They also deduced that it was a simple transition for employees who knew JavaScript but never worked with Node.

Bustle, an online media company, has reported achieving 70% savings by utilizing serverless and Node.js.

Developer Experience

Working in Node.js is truly a great experience, but you don’t have to take (only) my word for it.
The following photo highlights the most commonly used words by developers to describe their experience of working in Node:

Developer Productivity

The Developer Coefficient states that 96% of upper management finds that increasing developer productivity is a high/medium priority. They also think that just by improving developer productivity the company can achieve better results in sales, bring products to market faster, get ahead of their competitors and much more.

The truth is that developers can be as productive as the tools they use allow them to be.

Companies like Walmart, Netflix, OpenTable, and HomeAway have transitioned to Node.js and all report significant increases in developer productivity.

Node package managers

If we truly want to utilize the maximum potential of Node.js, we have to get familiar with the available package managers. Node packages are one of the main factors that allow fast development. Why rewrite code when you can use well-tested, open-source packages?
To handle the packages, you will need a package manager. Most commonly used package managers include npm, yarn and pnpm.

npm

npm is the default package manager and is most widely used. It is perfect for beginners and has terrific support. The previous versions had two main issues:

  • Initially, npm didn’t have a lock file. The exact versions of each dependency weren’t precisely stated. The code would be run with the latest versions which caused compatibility problems.
  • Npm wasn’t deterministic — different versions of packages were allowed on different machines.

Yarn fixed these problems and attracted a massive audience. Later, npm updates fixed the issues and made it as usable as Yarn.

If you don’t want the additional hassle and don’t care about the package install time or memory used, then you’ll be perfectly happy with npm.

Yarn

Yarn was built by Facebook with the goal to fix scalability issues npm had at the time. Three core principles of yarn are speed, reliability, and security. Yarn can install packages faster by using local caching — it is much faster to grab a package from cache memory than to wait for the download. Local caching also enables offline mode — packages in cache can be directly installed. Yarn was first to feature a file with locked package versions so the code wouldn’t be forcibly run on the latest version. Security is ensured with the use of checksums before execution.

There are some unique features of yarn which make it faster than npm. Installation of packages is parallel, while npm installs sequentially. Yarn guarantees that dependencies will be installed the same way on a different machine, regardless of the install order. Yarn removes mismatching versions of dependencies to avoid duplicates in node_modules. Better results are also seen in terms of network performance — requests are efficiently queued up so request waterfall is avoided and the network is fully utilized.

pnpm

If we have ten projects which use the same ten packages, each project will have its own copy in node_modules. This practice isn’t very efficient in terms of disk space. pnpm solves this problem by installing only one copy of the package on disk. The node_modules directory will only contain a hard link to the location of the package on the disk. Developers of the package manager claim it is as fast as yarn and npm — in some cases even faster. pnpm is strict in the sense that it only accesses the dependencies specified in package.json. It is great for multi-package repositories (monoreps).

Rush — Perfect for teamwork

Rush technically isn’t a package manager, but it allows you to pick out whether you want to use npm, yarn or pnpm. It enforces that the same version of the package manager is used by all team members. It was designed for monorepo management and helps organize the workflow if there are many components.

What’s next in the package manager world?

The next promising package manager is tink. It has been announced by npm developers and is still in development. It is said that tink will provide faster installs which will be run in the background. Files in the dependencies will be bit by bit identical to the ones in the registry. Working on a different project will only require cloning and running the project.

Tink acts as a replacement for Node.js, working from the package-lock.json file. It will enable you to run a project without node_modules. Node modules will be installed in the background. After a couple of seconds the server will start. If you take a look inside node_modules, you will find package-map.json instead of the modules. Package-map.json is made of hashes of all files in every package installed and is verified before being loaded to ensure security.

You can try it out here.

Conclusion

Node.js gets excellent performance as an architectural foundation for many Internet applications. The default package manager (npm) will work perfectly fine for most applications. If there are some specifications to your project which npm can’t satisfy, then you should have a look at the alternatives and see if they better suit your needs. Yarn can give you a speed-up and offline installation (in some cases), while pnpm will save additional disc space and is useful for multipacking repositories. If you want to see what the future will bring, download tink and give it a try.


I hope you enjoyed the article.
What are your experiences with node.js? Feel free to comment or ask anything below 👇🏼

Leave a Reply

Your email address will not be published.

After you leave a comment, it will be held for moderation, and published afterwards.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.