Let’s clean up chaos — managing multiple Javascript packages with Lerna.

Dominika Zając
4 min readFeb 5, 2021

--

Photo by Brett Jordan on Unsplash

It almost always looks the same. You start your super-hiper-new project from the scratch — using modern technologies, the newest tech features, and beautiful simple architecture. Your clients are happy and request more and more features. Your dev team is growing and the codebase is bigger and bigger. Some day you realize your package is so swollen that you have to split it into smaller ones… And here the fun part begins! Dependency management between repos becomes a nightmare — making changes between repositories needs more and more time, testing is more complicated, the number of bugs in the final product increases and the initial setup of all repositories (and understanding connections between them) makes junior developers almost cry. Fortunately, there are many tools that may save you from that scenario. Today, I wanna focus on one of them — monorepo approach based on Lerna.js (https://github.com/lerna/lerna).

Lerna official logotype — taken from https://github.com/lerna/lerna

What is a monorepo?

Monorepo is one of the approaches to manage packages in complex projects. All packages are located in the same git repository, so you keep all parts connected with the final project in one place. But at the same time, there are separated modules with independent versioning and dependencies. Each team can focus on their part, but changes are easy to test and release for the whole product. Also, you can create shared rules about e.g. linting and a common process for lint, build and release. The entry-level to project is lower because a new contributor needs to only clone one repository and call npm install & npx lerna bootstrap from the root — doesn’t care about dependencies between modules (lerna will handle it). Also, multi-packages changes are much easier. Of course, there are also cons of that approach — the repository is quite big, lerna can’t handle serverless monorepos, and may look a little overwhelming for a person who just starts work with monorepo. However, lerna can optimize the duplicated dependencies between modules (read about hoist mechanism) and a good README.md file and scripts in packages.json may help the beginners. In my personal opinion, the pros outweigh the cons. Many teams building the most recognizable software tools think the same — Babel, React and Jest are also monorepos!

Photo by Kevin Ku on Unsplash

So how to create a monorepo with lerna?

  • First of all, you have to install lerna (npm install lerna --save-dev is completely enough).
  • Later on, init your monorepo with npx lerna init
  • The above command will create the basic structure of the project — with global config files (package.json & lerna.json) and packages folder for your modules.
  • Create a new directory in the packages folder and put there your existing module or create it (e.g. with npm init). You can also use npx lerna import <package> to transfer your existing package into lerna repository (thanks to that commit history will be preserved).
  • Important! Don’t call npm install directly from your module — use npx lerna bootstrap instead. Thanks to that both: existing projects in the packages folder and external dependencies will be taken into account.
  • Add some useful scripts to the package.json file like:
"lint": "npx lerna run lint"
"test": "npx lerna run test"
"start": "npx lerna run start"
  • When you are ready, call npx lerna publish to publish all your modules (Read about fixed/locked mode to decide if you prefer to keep one version for all packages or independents for each of them).
  • Voilà! It’s all you need!

Final thoughts

Dependency management is not an easy task at all. There is no golden rule answering all cases and possibilities. Each project should be considered individually. But existing general approaches (like monorepo) and tools (like lerna) may help you to make a decision and avoid some mistakes. It’s why I strongly advise you to think about it and play a little with monorepos (e.g. in your side projects) — even if it’s not really necessary at this time in your main project. Maybe it will be useful with another? Or when your project will grow? Good luck

If you find this article interesting or useful, please, “clap” the button below or leave a comment. Happy coding!

--

--

Dominika Zając

Full-stack developer from Cracow, Poland. Google Developer Expert in Web. Passionate about a11y, best coding practices and singing.