Nx Complete Guide | Smart Monorepo Build System

Nx Complete Guide | Smart Monorepo Build System

이 글의 핵심

Nx is a smart, fast, and extensible build system for monorepos. It provides computation caching, task orchestration, and code generation for TypeScript/JavaScript projects.

Introduction

Nx is a next-generation build system with first-class monorepo support and powerful integrations. Created by former Angular team members at Nrwl, it’s designed for building at scale.

Why Nx?

Traditional monorepo:

# Build everything (slow!)
npm run build

# No caching
# No dependency graph
# No task orchestration

With Nx:

# Build only what changed
nx build

# Uses computation cache
# Understands dependencies
# Runs tasks in optimal order

1. Installation

New Workspace

npx create-nx-workspace@latest my-workspace

Options:

  • Integrated monorepo (recommended for new projects)
  • Package-based monorepo (for existing workspaces)
  • Standalone app (single project)

Add to Existing Project

npx nx@latest init

Works with existing npm/yarn/pnpm workspaces!

2. Basic Commands

# Run task
nx build my-app

# Run for all projects
nx run-many -t build

# Run affected (only changed projects)
nx affected -t build

# Show dependency graph
nx graph

# Show what's affected
nx show projects --affected

3. Workspace Structure

my-workspace/
├── apps/
│   ├── web/
│   │   ├── src/
│   │   ├── project.json
│   │   └── tsconfig.json
│   └── api/
│       ├── src/
│       └── project.json
├── libs/
│   ├── ui/
│   │   ├── src/
│   │   └── project.json
│   └── utils/
│       ├── src/
│       └── project.json
├── nx.json
├── package.json
└── tsconfig.base.json

4. Creating Projects

Generate App

# React app
nx g @nx/react:app web

# Next.js app
nx g @nx/next:app marketing

# Node.js app
nx g @nx/node:app api

Generate Library

# React library
nx g @nx/react:lib ui

# TypeScript library
nx g @nx/js:lib utils

# Nest.js library
nx g @nx/nest:lib data-access

5. Computation Caching

Nx caches task outputs:

# First run: builds and caches
nx build my-app
# Build time: 45s

# Second run: uses cache
nx build my-app
# Build time: 0.2s (from cache!)

What’s cached:

  • Build outputs
  • Test results
  • Lint results
  • Any custom task

Remote Caching

# Enable Nx Cloud
nx connect

# Now cache is shared across team and CI!
# Developer A builds
nx build my-app
# 45s, uploads to Nx Cloud

# Developer B builds same code
nx build my-app
# 0.5s, downloads from Nx Cloud

6. Task Dependencies

// apps/web/project.json
{
  "name": "web",
  "targets": {
    "build": {
      "executor": "@nx/webpack:webpack",
      "dependsOn": ["^build"], // Build dependencies first
      "outputs": ["{projectRoot}/dist"]
    },
    "test": {
      "executor": "@nx/jest:jest",
      "dependsOn": ["build"] // Build before test
    }
  }
}
# Builds 'ui' library first, then 'web' app
nx build web

7. Affected Commands

# Only test affected projects
nx affected -t test

# Only build affected projects
nx affected -t build

# Show what's affected
nx affected:graph

Use case:

  • PR contains changes to libs/ui
  • nx affected -t test only tests ui and projects that depend on it
  • Saves time in CI!

8. Task Orchestration

Run Multiple Tasks

# Run tests in all projects
nx run-many -t test

# Run build then test
nx run-many -t build test

# Parallel execution (default)
nx run-many -t build --parallel=3

Custom Task Pipelines

// nx.json
{
  "targetDefaults": {
    "build": {
      "dependsOn": ["^build"],
      "cache": true
    },
    "test": {
      "dependsOn": ["build"],
      "cache": true
    },
    "lint": {
      "cache": true
    }
  }
}

9. Generators

Create custom code generators:

# Generate generator
nx g @nx/plugin:generator my-generator
// tools/generators/my-generator/index.ts
export default async function (tree: Tree, schema: any) {
  // Generate files
  generateFiles(
    tree,
    join(__dirname, 'files'),
    'libs/new-lib',
    { name: schema.name }
  );
  
  // Update config
  await formatFiles(tree);
}
# Use generator
nx g my-generator --name=awesome-lib

10. Real-World Example: React Monorepo

# Create workspace
npx create-nx-workspace@latest my-company --preset=react-monorepo

cd my-company

# Generate apps
nx g @nx/react:app web
nx g @nx/react:app admin

# Generate shared libraries
nx g @nx/react:lib ui
nx g @nx/react:lib data-access
nx g @nx/js:lib utils

# Build everything
nx run-many -t build

# Test affected
nx affected -t test

Project structure:

my-company/
├── apps/
│   ├── web/                    # Customer-facing app
│   └── admin/                  # Admin dashboard
├── libs/
│   ├── ui/                     # Shared UI components
│   ├── data-access/            # API calls
│   └── utils/                  # Utilities
└── nx.json

11. CI/CD Optimization

GitHub Actions with Nx

name: CI

on: [push, pull_request]

jobs:
  main:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      
      - uses: actions/setup-node@v3
        with:
          node-version: 18
          cache: 'npm'
      
      - run: npm ci
      
      # Only test affected
      - run: npx nx affected -t test --base=origin/main
      
      # Only build affected
      - run: npx nx affected -t build --base=origin/main

With Nx Cloud

- run: npx nx affected -t test --base=origin/main --parallel=3
  env:
    NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}

Benefits:

  • Distributed task execution
  • Remote caching
  • Analytics dashboard

12. Migration Guides

From Lerna

npx nx init --integrated

Nx automatically:

  • ✅ Keeps your existing structure
  • ✅ Adds Nx configuration
  • ✅ Provides caching immediately

From CRA (Create React App)

npx nx init
nx g @nx/react:setup-ssr

Summary

Nx supercharges monorepo development:

  • Smart caching - never build twice
  • Affected commands - only build what changed
  • Task orchestration - optimal build order
  • Code generation - consistent project structure
  • Remote caching - share cache across team

Key Takeaways:

  1. Computation caching for faster builds
  2. Affected commands for CI optimization
  3. Task dependencies for correct build order
  4. Generators for consistent code
  5. Works with any npm workspace

Next Steps:

  • Try Turborepo
  • Setup Monorepo
  • Use pnpm

Resources: