# The package manager of exile.watch

<figure><img src="https://1213438767-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4DXEoZIzUdpt18CW2qTD%2Fuploads%2FzXjtfpnPjXaN7gAZDm9L%2Fexilewatch.webp?alt=media&#x26;token=74fc8000-b114-47be-bc13-cda9b75cd22f" alt="" width="256"><figcaption><p>exile.watch logo</p></figcaption></figure>

TL;DR: `exile.watch` is using NPM as it's package manager.&#x20;

NPM was causing the fewest issues, without really deteriorating the developer experience.

***

## What is a package manager?

Package manager is a tool that automates the process of installing, updating, configuring, and removing software packages or libraries from a project.&#x20;

These packages are typically distributed through a registry, with [npm](https://www.npmjs.com/) (Node Package Manager) being the most widely used registry in the JavaScript community.&#x20;

Package managers help developers manage dependencies (external code or libraries that a project relies on) efficiently and ensure consistency across development environments.

The most commonly used package managers in the JavaScript ecosystem are:

1. **npm**: The default package manager for Node.js, allowing users to install and manage dependencies from the npm registry.
2. **Yarn**: Developed by Facebook, Yarn is a faster, more secure alternative to npm, offering improvements in speed, reliability, and security for managing dependencies.
3. **pnpm**: Standing for "performant npm," pnpm offers efficiency by symlinking packages from a single content-addressable storage, reducing disk space usage and increasing installation speed compared to npm and Yarn.

## The good, the bad and everything around package managers regarding exile.watch development experience

### [npm](https://docs.npmjs.com/cli/v10/commands/npm)

In my experience with exile.watch, npm has been a reliable package manager, particularly appreciating its support for a multi-package approach through monorepo workspaces and the way it handles package dependencies in the root `node_modules`, aligning seamlessly with our architecture.&#x20;

However

* &#x20;the slow speed of `npm install` (well only few seconds, but comparing to other package managers - yeah, it's slow as fuck),
* rarely there is a need to run `npm run build` when using `npm link` to keep dependencies in sync flavored with general issues ([#2828](https://github.com/npm/cli/issues/2828), [#7151](https://github.com/npm/cli/issues/7151), [#4285](https://github.com/npm/cli/issues/4285), [#2076](https://github.com/npm/cli/issues/2076)),&#x20;
* coupled with the lack of hot reloading for `.next` dependencies (probably because of the aforementioned [#2828](https://github.com/npm/cli/issues/2828) issue since I'm on windows)

&#x20;are notable drawbacks that could (and did in some way at few points) impact productivity.

### [yarn](https://yarnpkg.com/)

The [exile.watch architecture](https://engineering.exile.watch/march-2024/exile.watch-architecture) aligns with the first three[ limitations and caveats](https://classic.yarnpkg.com/lang/en/docs/workspaces/#toc-limitations-caveats) of Yarn, leading me to initially dismiss Yarn due to its different package management philosophy.

Looking back, I realize this decision might have been premature. The documentation I referenced pertains to Yarn 1.x, which is quite outdated.&#x20;

Further research revealed that Yarn has progressed to version [4.x](https://yarnpkg.com/blog/release/4.0), far beyond the 2.x release I was vaguely aware of.&#x20;

This oversight is particularly regrettable because, throughout my 7-year career, I never professionally used Yarn, thus locking my understanding of this package manager in a medieval times.&#x20;

Which sucks, as I recall how effectively `yarn link` worked comparing to `npm link`.

### [pnpm](https://pnpm.io/)

When I first gave `pnpm` a go, the speed at which it handled installs was the first thing that made me take notice. It was impressively quick. And when I got into using `pnpm link` for hot reloading, it worked like a charm—no hiccups at all.

However, I soon hit a couple of bumps.&#x20;

One was with linking packages. It turned out that the `node_modules/.bin/` directory wasn’t getting the bin links from all the nested packages, which was a bit of a letdown because it messed with my continuous integration setup. (see [#96](https://github.com/pnpm/pnpm/issues/96) and [#899](https://github.com/pnpm/pnpm/issues/899)).

Then, there was `pnpm dedupe` step needed after installation. Not a deal-breaker, but definitely an extra hoop to jump through.

The binaries thing was a bit of a curveball too. Since the necessary bin executables from the nested packages weren’t automatically linked, `pnpm` tried to step in and fix the gap by installing them (and this was causing weird inconsistencies as well).&#x20;

This move kind of threw a wrench into my neat architecture plans, making things look more complex than I wanted. To get around that, I found myself resorting to the [`--shamefully-hoist`](https://pnpm.io/npmrc#shamefully-hoist).

But then I started experiencing inconsistencies with linking the packages locally akin to npm issues mentioned above.&#x20;

If I'm forcing pnpm to act as npm, then what's the point of using pnpm?

***

Author: [Sebastian Krzyżanowski](https://github.com/sbsrnt)\
About *exile.watch*: <https://docs.exile.watch/>\
Github: <https://github.com/exile-watch>\
\
Visit <https://exile.watch/> to experience it first hand
