Scalable architectures / Project management, tip 1: use NX as monorepo manager
Tags: react, typescript, vite, performance
Published: 2023-01-05 18:51:49

<small>Cover attribution: <a href="https://www.pexels.com/photo/a-champagne-bottle-against-a-light-pink-background-5379748/">Leeloo Thefirst</a> <small>

Generating and keeping the scaffolding of a Web application updated is one of the most complex tasks I have ever faced managing a project.

I won't go into the details of why I ended up choosing [NX](https://nx.dev/) over [Lerna](https://lerna.js.org/), [Turborepo](https://turbo.build/repo) and even [Bit](https://bit.dev/) for this task. Here I should clarify that the case of Bit is somewhat different because it manages each component as a separate library.

---

## Why NX?

I will simply show the power of NX with a simple example.

Create a Vite, React, Typescript monorepo quickly:

```sh
# NOTE: this gist uses pnpm as Node package manager
# and the next command alias is needed to work as
# expected:
alias pnx="pnpm nx"

# CREATE a new MONOREPO (Typescript, Github CI, pnpm):

# OPTION 1, FRAMEWORK preset type:
npx create-nx-workspace@latest @yourTeamId \
  --ci=github \
  --cli=nx \
  --nxCloud=true \
  --packageManager=pnpm \
  --preset=ts

# OPTION 2, APP preset type:
npx create-nx-workspace@latest @yourTeamId \
  --ci=github \
  --cli=nx \
  --nxCloud=true \
  --packageManager=pnpm \
  --preset=apps

# ---

# ADD a new LIB to previous created monorepo (Vite, 
# SWC, Vitest):
cd @yourTeamId
pnpm install -D @nrwl/js

# OPTION 1, WEB lib:
pnx g @nrwl/js:lib myWebLib \
  --importPath=@yourTeamId/myWebLib \
  --bundler=vite \
  --compiler=swc \
  --unitTestRunner=vitest \
  --publishable \
  --includeBabelRc \
  --tags=type:lib 

# OPTION 2, NODE lib:
pnx g @nrwl/js:lib myLib \
  --importPath=@yourTeamId/myLib \
  --bundler=vite \
  --compiler=swc \
  --unitTestRunner=vitest \
  --publishable \
  --testEnvironment=node \
  --tags=type:lib 

# ---

# ADD a new APP to monorepo (React, Vite, SWC,
# Vitest):
pnpm install -D @nrwl/react
pnx g @nrwl/react:application myApp \
  --importPath=@yourTeamId/myApp \
  --bundler=vite \
  --compiler=swc \
  --unitTestRunner=vitest \
  --routing \
  --tags=type:app

```

It works as expected? Try it:

```sh
# BUILD and run all TESTS
pnx run-many --target=test

# START app in DEV mode
pnx run myApp:serve

```

---

And of course this is just a simple example.

With NX you can publish libraries as npm packages, `pnx run myLib:publish`, and its ease of use invites you to create new libraries more frequently.

This last feature is what really makes your project scalable 😉.

---

## Create your own NX Plugin

It even allows us to create custom plugins to create a scaffolding tailored to your needs:

```sh
# ADD a new NX PLUGIN to monorepo (SWC):
pnpm install -D @nrwl/nx-plugin
pnx g @nrwl/nx-plugin:plugin yourPluginName \
  --importPath=@yourTeamId/yourPluginName \
  --compiler=swc \
  --tags=type:plugin

```

---

If you give it a chance it is likely to become a rewarding tool in your day to day life.

Thanks for reading me 😄.

Challenge: Why am I using tags when creating libraries and applications?

I look forward to your answer...