DEV Community

Cover image for Why I Switched To PNPM?
Harsh Rastogi
Harsh Rastogi

Posted on

Why I Switched To PNPM?

Package Manager For Node JS

It is system for that automate the process of adding/upgrading/removing and managing dependencies for a Node JS project

There are many package managers for Node JS

  • NPM (Node Package Manager)

Most popular package manager for Javascript and also default package manager for Node JS.

  • Yarn

It was released by Facebook Inc. in 2016. It was create to overcome problems and performance that were in NPM at that time.

  • PNPM

It is alternative package manager for Node Js for replacement of NPM, but faster and efficient.


Why is better than Yarn and NPM?

Imagine you install a package, Let call it Package_X. Imagine Lodash is one of dependency of Package_X. Now you install diffrent package call it Package_Y which also has Lodash as it dependency. Thus in a single project there two copies of Lodash.

If there are 100 packages using Lodash, you are going to have 100 copies Lodash

PNPM allows yoo to save tons of space

It is faster than both npm and yarn. Because Yarn copies files from cache wheareas pnpm links files into global score.

How PNPM works?

Note that PNPM doesn't flatten the dependency tree

Look how earlier node_modules tree looked like

node_modules/
|  Package_X/
|  | > node_modules/
|  |   | > Package_Z/
|  |       | index.js
|  |       | package.json
|  |   index.js
|  |   package.json
|
|  Package_Y/
|  | > node_modules/
|  |   | > Package_Z/
|  |       | index.js
|  |       | package.json
|  |   index.js
|  |   package.json
Enter fullscreen mode Exit fullscreen mode

This way to managing has some issuse

  • Deeply nested dependency tree, causing long directory names in system.

  • Packages are copied and pasted several times when they are required in different dependencies.

But now after update in NPM @version 3, they added flattening so structure look like

node_modules/
|  Package_X/
|  |   index.js
|  |   package.json
|
|  Package_Y/
|  |   index.js
|  |   package.json
|
|  Package_Z/
|  |   index.js
|  |   package.json
Enter fullscreen mode Exit fullscreen mode

But pnpm follow diffrent apporch rather than flattening tree it keeps it same

In /node_modules folder created by pnpm, each package has it's own dependency but dependency tree is never deep as in earlier version of npm. It keeps all dependencies flat with use of Symbolic Links or Junction (in windows)

node_modules/
|  Package_X/
|  | > node_modules/
|  |   | > Package_Z/ -> ../../../Package_Z/1.0.0
|  |   index.js
|  |   package.json
|
|  Package_Y/
|  | > node_modules/
|  |   | > Package_Z/ -> ../../../Package_Z/1.0.0
|  |       | index.js
|  |       | package.json
|  |   index.js
|  |   package.json
|
|  Package_Z/
|  |   index.js
|  |   package.json
Enter fullscreen mode Exit fullscreen mode

Installation

  • Open terminal
  • Execute following command
  npm install -g pnpm
Enter fullscreen mode Exit fullscreen mode

or

  npx pnpm add -g pnpm
Enter fullscreen mode Exit fullscreen mode

Small Project Using pnpm

We are going to build Restfull API that get name of two person and calculate the love percentage between them

Exexute below commands

Create a directory

  mkdir love-api
Enter fullscreen mode Exit fullscreen mode

Initialise it as pnpm project

  pnpm init -y
Enter fullscreen mode Exit fullscreen mode

We are going to use Express for it.
Note pnpm commands is quite similiar to both npm and yarn. We are going to replace npm install [PACKAGE_NAME] with pnpm add [PACKAGE_NAME]

So adding following packages to your projects

Execute below commands

  pnpm add express cors
Enter fullscreen mode Exit fullscreen mode
  pnpm add -D @types/express @types/cors nodemon typescript concurrently
Enter fullscreen mode Exit fullscreen mode

Add these below script to package.json

{
  "build": "tsc",
  "start": "node dist/index.js",
  "dev": "concurrently \"tsc -w\" \"nodemon dist/index.js\""
}
Enter fullscreen mode Exit fullscreen mode

We are going to discuss only about the PNPM side of things only
have look of source code here.

Dont Forget To Follow Me -> Harsh Rastogi

Now to build convert typescript code into javascript

In npm we do npm run build but in pnpm we have to execute

  pnpm build
Enter fullscreen mode Exit fullscreen mode

and to start dev server

  pnpm dev
Enter fullscreen mode Exit fullscreen mode

and to start server in production mode

  pnpm start
Enter fullscreen mode Exit fullscreen mode

Benchmarks

Benchmark compares the performance of NPM, Yarn, PNPM

Image description

Conclusion

If you are searching that gives you better speed and performance then pnpm is better, I personally suggest you to use pnpm instead of npm and Yarn. If you are not using it then you a chance to try it.

Yarn sends date to Facebook, which don't make yarn suitable in some scenarios. NPM has also security issue that's why there is Yarn now.

In above benchmarks we can see PNPM is better in all aspects.

Happy Coding :)

Top comments (5)

Collapse
 
woldtwerk profile image
Willi

If there are 100 packages using Lodash, you are going to have 100 copies Lodash

I don't think that's generally true. If you`re using a copy on write filesystem like brtfs or apfs you don't get copies like that. Without it yarn also offers a global cache.

Collapse
 
greybax profile image
Aleksandr Filatov

already done it in far far away 2019 alfilatov.com/posts/is-your-npm-in... :)

Collapse
 
theharshrastogi profile image
Harsh Rastogi

That year I began my journey with coding with C++, didn't know anything about Javascript. In 2020 started with Javascript and Node. My transition to the package manager was like NPN=>Yarn=>PNPM.

Collapse
 
trkaplan profile image
Tuncay Kaplan

Thanks for the post. If anyone want to use a shim to seamlessly alias @npm to @pnpm here is a snippet: gist.github.com/danielbayley/62a30...

Collapse
 
theharshrastogi profile image
Harsh Rastogi

Thank you, Tuncay for sharing this is something I come to know.