With Lerna in maintenance mode, even if its stewardship has recently moved to Nrwl, at Illimity, we started a scouting phase to understand which were the best alternatives and which of them could have been adopted.
The adoption of a new tool within a company is an operation that impacts multiple aspects.
One of these is productivity, it is necessary that the adoption is up to and does not create new problems over time.
To make the best choice on a possible new tool for managing monorepo we have performed some benchmarks.
Some operations are repeatedly performed by each of the 40 front-end developers throughout the day, even a small improvement on a single task can make a difference in the amount of work done.
Below we compare NX, Turborepo, and Lerna that we currently use.
Original measurements in decimal minutes, on one shared time axis. A dash means no result was reported. Lerna’s application-switch measurement uses no cache.
In the selected repository we have 13 typescript packages and 7 applications, each application mainly consumes more than 6 packages which must be transpile before the application can be startable. We will highlight the performance on two tasks currently present in the project, reset and install.
Currently, with the use of Lerna, the two tasks perform the following operations:
Reset: Switch between applications, or between branches with different functionalities, sometimes is necessary to delete node_modules folders and the build folders.
Install: For each application, it takes care of installing the required third dependencies and linking the packages declared as dependencies in the package.json. In addition, the dependencies required for the package must be installed and subsequently, the typescript code must be transpiled.
With Nx and Turborepo it was decided to exploit the main workspace functionality of npm, to connect local packages in a more declarative mode than the current one used, and to use the pnpm functionality, lines depend will be third downloaded just once, and reused in each project that will declare them in its package.json.
It is necessary to define a new install task, through the latter call up specific Nx or Turborepo functions and it will indicate to the tool which pipe to execute and the relative application.
For example, the install pipe declared in the nx.json configuration file targets 'transpile' task of each local package, to define the steps execution order to correctly start the application.
The first one includes the deletion of all node_modules folders and proceeds with the execution of the install task, which for each application installs the necessary dependencies and transpile the packages used.
We collected data with Nx and Turborepo's built-in caching mechanism disabled and later enabled.
| Task | Nx | Turborepo | Lerna |
|---|---|---|---|
| Reset | 2.41 | 2.15 · Fastest | 3.36 |
| Install | 1.21 · Fastest | 1.42 | 1.80 |
| Install · cache, first run | 1.18 · Fastest | 1.24 | — |
| Install · cache, second run | 0.17 · Fastest | 0.28 | — |
| Install · switch application | 0.14 · Fastest | 0.29 | 1.23 |
Original measurements in decimal minutes. Highlighted values are the fastest per task. A dash means no result was reported. Lerna’s application-switch measurement uses no cache.
The data show how Nx is slower than Turborepo in the execution of the reset task but in any other tasks, it is slightly faster. Unfortunately, Lerna does not have a caching mechanism, when the install command is executed each package is transpiled again.
In a monorepo environment a developer may have to switch from one application to another to start a new process or solve a bug, this metric shows how much time can be saved by migrating to Nx. With Nx and Turborepo, only not already transpiled packages will be transpiled.
We have also considered other aspects to understand which solution could be the best for our team, below we show a comparative table of some features offered by the three tools.
| Feature | Nx | Turborepo | Lerna |
|---|---|---|---|
| Distributed task execution | Included | Not included | Not included |
| Dependency graph visualization | Included | Included | Not included |
| Detecting affected projects/packages | Included | Included | Included |
| Project constraints and visibility | Included | Not included | Not included |
| Distributed computation caching | Included | Included | Not included |
| Local computation caching | Included | Included | Not included |
| Cache hit optimizations (Windows) | Included | Not included | Not included |
Original 2022 comparison. Only built-in, out-of-the-box features are marked as included.
While waiting to understand how Lerna will evolve, Nx seems to be the right solution for our needs, the speed for orchestration of the tasks, the cache optimizations, its diffusion, and all the features available make it a de-facto standard in the management of monorepo repositories.
Related Articles: