Can we implement a Monorepo structure without Yarn Workspaces or Lerna?

andreicalazans profile image Andrei Xavier de Oliveira Calazans ・2 min read

In order to simplify dependency management, code reuse, and collaboration across teams, many projects have sought out to use the Monorepo structure.

To implement this structure most projects decide either on Yarn Workspaces or Lerna to accomplish this feat. The difference between the two can be simplified to the fact Lerna can do everything Yarn Workspaces can including use it as a base, and provide sophisticated publishing and version management features to even publish projects independently from each other.

The Problem

Yarn Workspaces has proven to be quite burdensome to maintain when working with React Native due to React Native's assumptions. Overall, as your codebase progress and new updates occur, you might need to update and fix the Monorepo structure. To avoid having this kind of issue, and to also enjoy similar benefits. You could instead structure your Monorepo without Workspaces.

How could we structure a Monorepo without Yarn Workspaces?

Under the same repository, you could have multiple independent projects linked by installing it via a relative path. Each project or module will have its own package.json file which you can create with yarn init.

- apps
   - app_one
   - app_two
- shared
   - module_one
   - module_two

app_one and app_two can consume the shared module by installing it as follow:

yarn add file:../../shared/module_one
This will add the following to your package.json 

"module_one": "file:../../shared/module_one",

Note, To avoid reinstalling the same dependencies make sure to declare modules as peerDependencies inside your shared modules if you also use them.

This approach has the benefit of being compatible with NPM as well.

Possible Problems

If your shared modules have external dependencies and for some reason, you install them by running yarn inside shared/*, you have to always remember to remove the node_modules folder before running your app, else you will have name collisions.


There is a price to be paid by abstractions. This does not mean abstractions are negative, it only means we should look for simplicity to achieve our goals, else we will die maintaining. I hope this post displayed a simple and less abstracted way to handle Monorepo structures.


markdown guide

Some time ago, I read in a Typescript book that it has some structure that the idea of ​​monorepo would be possible.
I don't remember now, but I think it was something like TS Projects.