--- Nx Monorepo Series 1: Introduction & Spring Boot Integration
Home โ†’ Blog โ†’ Nx Monorepo Series 1: Introduction & Spring Boot Integration

Nx Monorepo Series 1: Introduction & Spring Boot Integration

Learn how to set up a modern monorepo using Nx and integrate Spring Boot applications - the same architecture used by Google, Facebook, and other tech giants.

Nx Monorepo Series 1: Introduction & Spring Boot Integration

Nx Monorepo Series 1: Introduction & Spring Boot Integration

Part 1 of 5: Building Enterprise-Grade Monorepos with Nx

Learn how to set up a modern monorepo using Nx and integrate Spring Boot applications - the same architecture used by Google, Facebook, and other tech giants.


What is a Monorepo?

A monorepo (monolithic repository) is a software development strategy where code for multiple projects is stored in a single repository. Instead of having separate repositories for each project, application, or library, everything lives together in one unified codebase.

Key Characteristics

  • Single Repository: All code lives in one Git repository
  • Multiple Projects: Contains multiple applications, services, and libraries
  • Shared Dependencies: Common code and dependencies are shared across projects
  • Unified Versioning: Single source of truth for versions and configurations
  • Atomic Commits: Changes across multiple projects can be committed together

Example Structure

my-company-monorepo/
โ”œโ”€โ”€ apps/
โ”‚   โ”œโ”€โ”€ web-app/              # React frontend
โ”‚   โ”œโ”€โ”€ mobile-app/           # React Native app
โ”‚   โ”œโ”€โ”€ api-service/          # Node.js backend
โ”‚   โ””โ”€โ”€ admin-dashboard/      # Angular admin panel
โ”œโ”€โ”€ libs/
โ”‚   โ”œโ”€โ”€ shared-ui/            # Shared UI components
โ”‚   โ”œโ”€โ”€ auth/                 # Authentication library
โ”‚   โ”œโ”€โ”€ data-models/          # Shared data models
โ”‚   โ””โ”€โ”€ utils/                # Utility functions
โ””โ”€โ”€ tools/
    โ””โ”€โ”€ scripts/              # Build and deployment scripts

What is Nx?

Nx is a powerful open-source build system and monorepo management tool that takes monorepo development to the next level.

Core Features

1. Smart Build System

  • Only rebuilds what changed
  • Distributed task execution
  • Computation caching (local and remote)

2. Dependency Graph

  • Understands project relationships
  • Visualizes dependencies
  • Runs tasks in optimal order

3. Code Generators

  • Scaffolds new projects quickly
  • Ensures consistency across codebase
  • Reduces boilerplate

4. Integrated Tooling

  • Built-in support for testing, linting, building
  • Plugin ecosystem for popular frameworks
  • IDE integration

5. Scalability

  • Handles hundreds of projects
  • Efficient CI/CD pipelines
  • Distributed caching with Nx Cloud

Supported Technologies

  • Frontend: React, Angular, Vue, Next.js, React Native
  • Backend: Node.js, NestJS, Express
  • Mobile: React Native, Expo, Ionic
  • Build Tools: Webpack, Vite, esbuild, Rollup
  • JVM: Java (Gradle, Maven), Kotlin, Scala
  • Other: Python, Go, .NET

Why Use a Monorepo?

1. Code Sharing Made Easy

Before Monorepo (Polyrepo):

  • Publish library to npm
  • Update package.json in 5 different repos
  • Deal with version conflicts
  • Wait for CI/CD pipelines

With Monorepo:

  • Import directly from shared library
  • Changes are immediately available
  • Single version, no conflicts
  • Refactor across all projects at once

2. Atomic Changes

// Single commit can update:
// - API endpoint in backend
// - API client in shared library
// - UI component using the API
// - Tests for all affected code
// - Documentation

// This is impossible in polyrepo without:
// - Multiple PRs across repos
// - Coordinated merges
// - Version management headaches

3. Consistent Tooling

  • One ESLint config for all projects
  • One TypeScript config
  • One testing framework setup
  • One CI/CD pipeline
  • One set of dependencies to manage

4. Better Refactoring

  • IDE can refactor across all projects
  • Find all usages of a function across the entire codebase
  • Rename safely with confidence
  • No broken dependencies between repos

5. Improved CI/CD Efficiency

# Nx only runs tasks for affected projects
nx affected -t test    # Only test changed projects
nx affected -t build   # Only build what's needed
nx affected -t lint    # Only lint changed code

# See which projects are affected
nx show projects --affected

# Visualize affected project graph
nx graph --affected

# Traditional approach: Run everything, every time

6. Enhanced Developer Experience

  • Clone once, work on everything
  • Single onboarding process
  • Easier to discover and reuse code
  • Consistent coding standards

Monorepo vs Polyrepo

Polyrepo (Multiple Repositories)

company-frontend/     (separate repo)
company-backend/      (separate repo)
company-mobile/       (separate repo)
company-shared-lib/   (separate repo, published to npm)

Advantages:

  • โœ… Clear ownership boundaries
  • โœ… Independent deployment
  • โœ… Smaller repository size
  • โœ… Team autonomy

Disadvantages:

  • โŒ Difficult to share code
  • โŒ Version management complexity
  • โŒ Coordinated changes require multiple PRs
  • โŒ Duplicate dependencies
  • โŒ Inconsistent tooling
  • โŒ Hard to refactor across projects

Monorepo (Single Repository)

company-monorepo/
โ”œโ”€โ”€ apps/
โ”‚   โ”œโ”€โ”€ frontend/
โ”‚   โ”œโ”€โ”€ backend/
โ”‚   โ””โ”€โ”€ mobile/
โ””โ”€โ”€ libs/
    โ””โ”€โ”€ shared/

Advantages:

  • โœ… Easy code sharing
  • โœ… Atomic changes
  • โœ… Single source of truth
  • โœ… Consistent tooling
  • โœ… Better refactoring
  • โœ… Simplified dependency management

Disadvantages:

  • โŒ Requires proper tooling (Nx solves this)
  • โŒ Larger repository (mitigated by Nx caching)
  • โŒ Need for good monorepo practices
  • โŒ Potential for tight coupling (if not careful)

Real-World Examples

Google - The Largest Monorepo

Statistics:

  • 86 TB of data (as of 2015)
  • 2 billion lines of code
  • 35 million commits
  • Thousands of developers
  • Millions of files

Tool Used: Google created Bazel (now open-source)

Why Google Uses Monorepo:

  • Code reuse across entire company
  • Unified tooling and standards
  • Large-scale refactoring capabilities
  • Atomic changes across services
  • Single version of every dependency
  • Easier collaboration

Facebook/Meta

  • Hundreds of thousands of files
  • React, React Native, Jest developed here
  • Code sharing between Facebook, Instagram, WhatsApp
  • Tool: Custom Mercurial + Buck build system

Microsoft

  • Windows operating system
  • Office suite
  • Many internal tools
  • Tool: Git with Virtual File System (VFS for Git)

Other Notable Companies

  • Uber: Bazel (thousands of microservices)
  • Airbnb: Bazel + Custom tooling
  • Twitter: Bazel + Pants

When to Use a Monorepo

โœ… Ideal Use Cases

  1. Multiple Related Applications

    • E-commerce platform with web, mobile, admin panel
    • SaaS product with customer app + admin dashboard
    • Microservices that share code
  2. Shared Libraries

    • UI component library used across apps
    • Common utilities and functions
    • Shared data models
  3. Full-Stack Development

    • Frontend + Backend in same repo
    • Type sharing between client and server
    • API contracts in one place
  4. Platform Products

    • Multiple products sharing infrastructure
    • White-label applications
    • Multi-tenant systems
  5. Enterprise Applications

    • Large organizations with many teams
    • Need for consistency
    • Complex dependencies

โŒ When to Avoid Monorepo

  1. Completely Independent Products

    • No shared code
    • Different teams, different stacks
    • No coordination needed
  2. Some Open Source Projects

    • Contributors may only care about one part
    • Separate release cycles
    • Different governance models
  3. Very Different Tech Stacks

    • No overlap in dependencies
    • No shared tooling
    • No benefit from unified workflow

Nx Architecture

Core Components

1. Nx Workspace Structure

my-workspace/
โ”œโ”€โ”€ nx.json                 # Nx configuration
โ”œโ”€โ”€ package.json            # Dependencies (optional)
โ”œโ”€โ”€ apps/                   # Applications
โ”œโ”€โ”€ libs/                   # Libraries
โ””โ”€โ”€ .nx/                    # Nx cache and metadata

2. Project Configuration

// apps/my-app/project.json
{
  "name": "my-app",
  "projectType": "application",
  "targets": {
    "build": { "executor": "@nx/webpack:webpack" },
    "serve": { "executor": "@nx/webpack:dev-server" },
    "test": { "executor": "@nx/jest:jest" }
  }
}

3. Dependency Graph

Nx provides visual representation of project dependencies:

nx graph  # Opens browser with interactive graph

4. Computation Caching

# First run: Actually builds
nx build my-app  # Takes 30s

# Second run: From cache
nx build my-app  # Takes 0.1s โšก

Step-by-Step: Creating Nx Monorepo from Scratch

Prerequisites

Ensure you have the following installed:

# Node.js v18 or higher
node --version

# npm
npm --version

# Java 17+ (for Spring Boot)
java -version

# Git
git --version

Step 1: Create Empty Git Repository

# Create directory
mkdir my-monorepo
cd my-monorepo

# Initialize git
git init

# Create initial README
echo "# My Monorepo" > README.md
git add README.md
git commit -m "Initial commit"

Step 2: Initialize Nx

# Initialize Nx with npm preset
npx nx@latest init --preset=npm --workspaceType=integrated --nxCloud=skip

Command Breakdown:

  • nx@latest init - Initializes Nx in current directory
  • --preset=npm - Uses npm for package management
  • --workspaceType=integrated - Creates integrated monorepo
  • --nxCloud=skip - Skips Nx Cloud setup (can add later)

Step 3: Verify Installation

# Check created files
ls -la

# You should see:
# - nx.json           (Nx configuration)
# - .gitignore        (Git ignore file)
# - nx / nx.bat       (Nx wrapper scripts)
# - .nx/              (Nx cache and installation)

# Check Nx version
./nx --version

# List available plugins
./nx list

Step 4: Understand Generated Structure

my-monorepo/
โ”œโ”€โ”€ .git/                  # Git repository
โ”œโ”€โ”€ .gitignore            # Git ignore patterns
โ”œโ”€โ”€ .nx/                  # Nx installation and cache
โ”‚   โ”œโ”€โ”€ nxw.js           # JavaScript wrapper
โ”‚   โ””โ”€โ”€ installation/    # Nx packages
โ”œโ”€โ”€ nx                    # Unix wrapper script
โ”œโ”€โ”€ nx.bat               # Windows wrapper script
โ”œโ”€โ”€ nx.json              # Nx configuration
โ””โ”€โ”€ README.md            # Documentation

Step 5: Initial nx.json Configuration

{
  "installation": {
    "version": "22.2.3"
  },
  "$schema": "./node_modules/nx/schemas/nx-schema.json"
}

Step 6: Commit Initial Setup

git add .
git commit -m "Initialize Nx monorepo"

Adding Spring Boot to Nx

Now letโ€™s integrate Spring Boot with our Nx workspace.

Step 1: Install Gradle Plugin

# Method A: Using Nx (may be slower)
./nx add @nx/gradle

# Method B: Direct installation (faster)
cd .nx/installation
npm install @nx/gradle@22.2.3
cd ../..

Step 2: Update nx.json

{
  "installation": {
    "version": "22.2.3",
    "plugins": {
      "@nx/gradle": "22.2.3"
    }
  },
  "$schema": "./node_modules/nx/schemas/nx-schema.json"
}

Step 3: Initialize Gradle Support

./nx generate @nx/gradle:init

This updates your nx.json with Gradle plugin configuration:

{
  "installation": {
    "version": "22.2.3",
    "plugins": {
      "@nx/gradle": "22.2.3"
    }
  },
  "$schema": "./node_modules/nx/schemas/nx-schema.json",
  "plugins": [
    {
      "plugin": "@nx/gradle",
      "options": {
        "testTargetName": "test",
        "classesTargetName": "classes",
        "buildTargetName": "build"
      }
    }
  ],
  "namedInputs": {
    "default": ["{projectRoot}/**/*"],
    "production": ["default", "!{projectRoot}/src/test/**/*"]
  }
}

Step 4: Create Apps Directory

mkdir -p apps

Step 5: Generate Spring Boot Project

Use Spring Initializr to create your project:

curl https://start.spring.io/starter.zip \
  -d dependencies=web,data-jpa,h2,actuator \
  -d type=gradle-project \
  -d language=java \
  -d bootVersion=3.4.0 \
  -d javaVersion=21 \
  -d groupId=com.example \
  -d artifactId=spring-api \
  -d name=SpringApi \
  -d packageName=com.example.springapi \
  -o apps/spring-api.zip

# Extract the project
cd apps
unzip spring-api.zip -d spring-api
rm spring-api.zip
cd ..

Step 6: Create Nx Project Configuration

Create apps/spring-api/project.json:

{
  "name": "spring-api",
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
  "projectType": "application",
  "sourceRoot": "apps/spring-api/src",
  "targets": {
    "build": {
      "executor": "@nx/gradle:gradle",
      "outputs": ["{projectRoot}/build"],
      "options": {
        "taskName": "build"
      }
    },
    "serve": {
      "executor": "@nx/gradle:gradle",
      "options": {
        "taskName": "bootRun"
      }
    },
    "test": {
      "executor": "@nx/gradle:gradle",
      "outputs": ["{projectRoot}/build/test-results"],
      "options": {
        "taskName": "test"
      }
    },
    "clean": {
      "executor": "@nx/gradle:gradle",
      "options": {
        "taskName": "clean"
      }
    }
  },
  "tags": ["type:app", "platform:jvm"]
}

Step 7: Verify Project Setup

# List all projects
./nx show projects
# Output: spring-api

# Build the project
./nx build spring-api

# Run the application
./nx serve spring-api

Step 8: Create a REST Controller

Create apps/spring-api/src/main/java/com/example/springapi/HelloController.java:

package com.example.springapi;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello from Spring Boot in Nx Monorepo! ๐Ÿš€";
    }

    @GetMapping("/")
    public String home() {
        return "Welcome to Spring API - Powered by Nx";
    }
}

Step 9: Test Your API

# Start the server
./nx serve spring-api

# In another terminal, test the endpoints
curl http://localhost:8080/hello
# Output: Hello from Spring Boot in Nx Monorepo! ๐Ÿš€

curl http://localhost:8080/
# Output: Welcome to Spring API - Powered by Nx

Step 10: Commit Your Work

git add .
git commit -m "Add Spring Boot API with Nx integration"

Essential Nx Commands

Here are the key commands youโ€™ll use regularly:

# Check Nx version
./nx --version

# List all projects
./nx show projects

# Show project details
./nx show project spring-api

# Build a project
./nx build spring-api

# Run/serve a project
./nx serve spring-api

# Run tests
./nx test spring-api

# Clean build artifacts
./nx clean spring-api

# View dependency graph
./nx graph

# Clear Nx cache
./nx reset

# Run command for multiple projects
./nx run-many -t build -p spring-api,another-app

# Show which projects are affected by changes
./nx show projects --affected

# Visualize affected project dependency graph
./nx graph --affected

# Run command only for affected projects
./nx affected -t test
./nx affected -t build
./nx affected -t lint

# Advanced affected commands
# Run affected with specific base branch
./nx affected -t test --base=origin/main

# Run affected comparing to a specific commit
./nx affected -t test --base=HEAD~1

# Dry run (see what would be affected)
./nx affected -t test --dry-run

# Run affected in parallel
./nx affected -t test --parallel=3

# Skip cache for affected
./nx affected -t test --skip-nx-cache

๐ŸŽ‰ Congratulations!

Youโ€™ve successfully completed Series 1 of the Nx Monorepo tutorial!

What Youโ€™ve Accomplished

  • โœ… Understanding monorepo architecture used by tech giants
  • โœ… Set up an Nx monorepo from scratch
  • โœ… Installed and configured @nx/gradle plugin
  • โœ… Integrated Spring Boot 3.4 with Java 21
  • โœ… Created REST API endpoints
  • โœ… Successfully built and ran Spring Boot using Nx

Your Spring Boot API is now running in an enterprise-grade Nx monorepo with:

  • ๐Ÿš€ Smart caching for faster builds
  • ๐Ÿ“Š Dependency tracking
  • ๐Ÿ—๏ธ Scalable architecture
  • ๐Ÿ› ๏ธ Professional tooling

๐Ÿš€ Coming in Series 2: Full-Stack Development

In the next part of this series, weโ€™ll expand our monorepo:

Whatโ€™s Next

  • ๐Ÿ“ฑ Adding a React/Next.js Frontend
  • ๐Ÿ”— Frontend-Backend Integration
  • ๐Ÿ“ฆ Code Sharing Between Projects
  • ๐ŸŽฏ Running Full-Stack Together
  • ๐Ÿงช Testing Full-Stack Applications

Teaser Commands

# Coming in Series 2:
./nx add @nx/react
./nx generate @nx/react:application web
./nx run-many -t serve -p spring-api,web

Stay tuned for Series 2! ๐Ÿ“šโœจ


Additional Resources

Official Documentation

Monorepo Concepts

Community


Conclusion

Youโ€™ve learned the fundamentals of monorepo architecture and successfully integrated Spring Boot with Nx! This foundation will serve you well as we explore more advanced topics in upcoming series.

Key Takeaways

  • ๐Ÿ—๏ธ Monorepos enable better code sharing and consistency
  • ๐Ÿš€ Nx provides enterprise-grade tooling
  • โ˜• Spring Boot integrates seamlessly via Gradle plugin
  • ๐Ÿ“Š Tech giants trust monorepo architecture for good reasons

In Series 2, weโ€™ll add a frontend application and explore full-stack development in the Nx monorepo!


About This Series

This is Part 1 of the Nx Monorepo Series:

  • โœ… Series 1: Introduction to Nx & Spring Boot Integration (You are here)
  • ๐Ÿ”œ Series 2: Full-Stack Development with React/Next.js
  • ๐Ÿ”œ Series 3: Shared Libraries & Code Reuse
  • ๐Ÿ”œ Series 4: Advanced Nx Features & CI/CD
  • ๐Ÿ”œ Series 5: Multi-Technology Monorepo

Repository: github.com/kreasipositif/demo-monorepository


Ready to master modern monorepo architecture? Join our comprehensive development courses at Kreasi Positif Indonesia and learn industry best practices from experienced software engineers.