DEV Community

Kinga
Kinga

Posted on

Why Rush?

After happily using Lerna for quite some time, I feel I should move on.
This article is a fully subjective review of Rush, outlining some pros and cons I find important for my SPFx projects. In the next articles of the series I will show my approach to some obstacles I see.

Rush

Rush is owned by Microsoft, and since January 2017 is an open source project. You may find a little history here.
Rush statistics.

Package Manager Support

Lerna Rush ⭐
✔️ npm
❌ pnpm
✔️ yarn
✔️ npm
✔️ pnpm
✔️ yarn

Can I rest my case now?
Pnpm is a big deal. It solves phantom dependencies and NPM doppelganger problems, and if that's not enough, it's also faster and users less disk space. There's a request for pnpm support by lerna, opened in 2018. I'm not holding my breath.

Monorepo management

Dependencies support

Lerna Rush ⭐
For monorepos, lerna bootstrap --hoist installs external dependencies at the repo root, so they're available to all packages.
This increases the risk of phantom dependencies.
Installs package dependencies in common/temp/node_modules and updates the shrinkwrap file in common/config/rush folder to store a central inventory of all dependencies and versions for projects in the repo.
Rush uses symlinks to reconstruct an accurate node_modules folder for each project, based on the shrinkwrap file.

Rush & phantom dependencies

Rush's symlinking strategy ensures that each project's node_modules contains only its declared direct dependencies. This catches phantom dependencies immediately at build time. If you're using the PNPM package manager, the same protections are also applied to all indirect dependencies (with the ability to workaround any "bad" packages by using pnpmfile.js).

Rush & doppelgangers

Rush's symlinking strategy eliminates doppelgangers only for dependencies that are local projects in the monorepo. If you're using NPM or Yarn as your package manager, unfortunately doppelgangers are still possible for any indirect dependencies. Whereas if you use PNPM with Rush, the doppelganger problem is fully solved (because PNPM's installation model accurately simulates a true directed acyclic graph).

Selectively build and publish

Yes and yes, although I find rush to give me more flexibility.

Lerna Rush
lerna run --scope PROJECT build





rush build [--to PROJECT]
[--to PROJECT]
[--from PROJECT]
[--only PROJECT]
[--impacted-by PROJECT]
[--impacted-by-except PROJECT]
lerna publish
Control which package should get published using "private": true or "private": false in the package.json. Private packages never get published.
Use lerna publish --force-publish=package-2,package-4 to decide which packages get published.
rush publish
Control which package should get published using shouldPublish in rush.json.
Use rush publish --include-all so that all packages with shouldPublish=true in rush.json or with a specified version policy will be published if their version is newer than published version.

Independent versioning

Lerna Rush
Configured in lerna.json
independent versioning in lerna











Configured in common\config\rush\version-policies.json independent versioning in rush step1 and also in rush.json independent versioning in rush step2

Versioning and Conventional Commits

This was a surprise.

Lerna ⭐ Rush
lerna version --conventional-commits uses use the Conventional Commits Specification to determine the version bump and generate CHANGELOG.md files. Interestingly, chore commit will also cause version bump.






Rush has entirely different approach here.
Developers, apart from committing their changes, are required to run rush change command to generate change files. rush change prompts for a change description and a type of change (major/minor/patch). No Conventional Commits support, no use of commit messages.
The change files are stored in common\changes folder and are later used to update changelog.

Git hooks

Lerna Rush ⭐
Yes, with husky. Yes, see installing Git hooks.

I'm giving Rush a ⭐ here because it offers support, if the code invoked by git hook has dependencies on additional modules.

npm lifecycle support

Lerna ⭐ Rush
Lerna runs npm lifecycle scripts during lerna version. There seems to be a problem, but I think I can overcome it with custom commands

My decision

Lerna and Rush both have pros and cons. I really see a difference when using pnpm, so I'm going to stick with Rush.
I only have to solve the issue with changelog generation.

Top comments (0)