Monorepos and Nx
Tags: react, typescript, javascript
Published: 2021-09-01 20:22:36

## What's a Monorepo?
A `monorepo` is a single repository that can have one or more projects inside of it. You can have frontend, backend and helper tools, all in the same `monorepo`.

You could have a customer and a backoffice applications, both living in separate folders consuming an API living in another folder and a set of `interfaces` that would be shared by your applications and APIs.

If you had a `multi-repo`, one `repository` would contain the `customer` application, another one, the `backoffice`, another one would have the `API` and another for the `interfaces`. Maybe all of your applications would consume the `API` and the `interfaces` through a `package` published on the `npm` or some other package manager.

## Why should you use it?
If you're working in a company or a team, most certainly they will have best practices and code standards defined and if they don't, they will have them sooner or later. 

Also as the company grows in people and in complexity you will have separate teams working to achieve the same or correlate goals. You could have a frontend and a backend team, both working to achieve the same goal in different repositories and this could lead to some problems in the future, like duplicated `types`,  slow development and deliver time and so on.

A `monorepo` addresses some of those issues by having everything in the same `repository`. Some of the benefits are:

- Maintain your company best practices in one place and apply them without much effort
- Every best practice that you have, would be adopted by every project automatically with the help of tools like `eslint` and `prettier`
- It's easier to share code between your projects
- The shared code it's easier to maintain
- Changes that you make could be reflected on every project in the same time that that they're made

## Drawback of a Monorepo

Even though it's has a lot of benefits, like all things in life, it comes with some drawbacks

- Every change to your shared code will reflect on every application that you have. So, you need to make sure that everything is still working as expected in every affected application
- Performance issues with your VCS (version system control) as your `monorepo` grows in size.
- It's hard for your team/company to give specific access permissions to specific teams, since everything is in the same `repository`.
- Applying some specific rules to your `monorepo` could be a problem. Like getting some specific parts of it and make it `open-source`. That's not easy to accomplish and probably you would need some specific tools to help you with that.

## Nx, a tool to help you manage your `monorepo`
And then comes `Nx`. A tool that aims to facilitate the process of managing a `monorepo` by providing a set of helpers and commands that the developers and the maintainers could use to organize and develop faster within a `monorepo`.

It's main structure consists of two folders:

### /Apps
It's a place to store all of your applications and their `e2e` tests. For example, you could have a website for your customer and one for your backoffice, and they both could consume some `components` created on the `libs` folder.

### /Libs
It's where you'd store every code that you want to share between your applications created on the `apps` folder. For example, you could have a `components library` inside that folder and use the components created there inside your `applications` without a lot of effort. You could also have an API that would be used by your apps for example.

### Code example
Imagine that you have the following button inside `/libs/button`

```jsx
export const Button = ({ onClick, children }) => {
	return <button onClick={onClick}>{children}</button>
}
```

And then, you want to use that button inside your application that it's located in `/apps/customer`. It's easy as that

```jsx
import { Button } from '<your-monorepo-name>/button';

export const CustomPage = () => {
	function handleClick() {}

	return (
		<div>
			This could be a form
			<Button onClick={handleClick}>Submit</Button>
		</div>
	)
}
```

## Why Nx?

### Nx helpers
Nx comes with `pre-built` generators that aims to facilitate the process of creating Applications and Libraries with `React`, `Angular` and many other frameworks. These `generators` can be used by with the help of commands that you run on your terminal and it will generate and add code inside your folders and update any other files that may be necessary.

And you can also create your own `generators` to suit your team and company needs.

### Other things
- It has a very good VsCode extension that make it easier to manage the `monorepo`
- IT has a `dependency graph` that helps knowing which part of your application should be builded again and tested when somethings changes
- It has a single `package.json` file in the root of the `monorepo` which aims to make all of your code use the same `dependency` versions
- It caches all of your commands, like build and test ones. So, the first time that you run some command, it could take a while, but after that, it will be blazingly fast because of the cache that was made.

## Conclusion
The choice between going with a `multi-repo` or `monorepo` is a difficult one, both of them come with their own set of benefits and drawbacks. One thing that I can say to you is to balance them out with your team and organization to choose the right tool for the job.

Feel free to [send me a tweet and follow me on twitter](https://twitter.com/samuelmpinho) 🤙