DEV Community

Cover image for Scalable architectures / Project management, tip 1: use NX as monorepo manager
Julián Mulet
Julián Mulet

Posted on • Edited on

Scalable architectures / Project management, tip 1: use NX as monorepo manager

Cover attribution: Leeloo Thefirst

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 over Lerna, Turborepo and even Bit 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:

# 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

Enter fullscreen mode Exit fullscreen mode

It works as expected? Try it:

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

# START app in DEV mode
pnx run myApp:serve

Enter fullscreen mode Exit fullscreen mode

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:

# 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

Enter fullscreen mode Exit fullscreen mode

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...

Top comments (0)