DEV Community

Nexa Soul
Nexa Soul

Posted on

"Setting Up Your First Nx Monorepo in 10 Minutes" - A quick-start guide with practical examples

 You are in the perfect spot if you have been hearing about monorepos and are wondering what all the hype is about. Today we'll establish an Nx monorepo from the ground up, create a small workspace with a React app and a shared library. All in around 10 minutes.
What is Nx?
Nx is a strong monorepo solution and build system that assists you in controlling several projects in one repository. Consider it your development workstation on steroids—built right in with intelligent caching, code generation, and dependency management.

Why Should You Concern?

Code Sharing: Reuse types, utilities, and components across several applications.
One setup for linting, testing, and construction is constant tooling.
Smart Builds: Nx only rebuilds what changed, saving you tons of time
Scalability: Start small, grow big—Nx scales with your needs

Enough talk, let's build something!

Prerequisites
Before we begin, you have:

Node.js (v18 or above)
installed npm, yarn, or pnpm
Simple knowledge of React (or your chosen framework)

Step 1: Create Your Nx Workspace (2 minutes)
Open your terminal and run:
npx create-nx-workspace@latest my-nx-workspace
You'll be prompted with several questions. Here's what I recommend for this tutorial:
✔ Which stack do you want to use? · react
✔ What framework would you like to use? · none
✔ Integrated monorepo, or standalone project? · integrated
✔ Application name · todo-app
✔ Which bundler would you like to use? · vite
✔ Test runner to use for end to end (E2E) tests · none
✔ Default stylesheet format · css
✔ Enable distributed caching · No

Nx will now create your workspace. Once done, navigate into it:
cd my-nx-workspace
Step 2: Explore the Generated Structure (1 minute)
Take a quick look at what Nx created:

my-nx-workspace/
├── apps/
│   └── todo-app/              # Your React application
├── libs/                      # Shared libraries go here
├── nx.json                    # Nx configuration
├── package.json
└── tsconfig.base.json
Enter fullscreen mode Exit fullscreen mode

The apps/ folder contains your applications, while libs/ will hold shared code. Clean and organized!
Step 3: Create a Shared Library (2 minutes)
Let's create a shared UI library that our app (and future apps) can use:
npx nx g @nx/react:library ui --directory=libs/ui
When prompted, choose:

Which unit test runner would you like to use? → vitest
Which bundler would you like to use? → vite

Nx just generated a complete library with:

Component structure
Testing setup
Build configuration

Check out libs/ui/src/lib/ to see the generated component

Step 4: Create a Custom Component (2 minutes)
Let's create a simple Button component in our UI library. Create a new file:
libs/ui/src/lib/button/button.tsx

export interface ButtonProps {
  label: string;
  onClick?: () => void;
  variant?: 'primary' | 'secondary';
}

export function Button({ label, onClick, variant = 'primary' }: ButtonProps) {
  const styles = {
    primary: {
      backgroundColor: '#007bff',
      color: 'white',
      border: 'none',
      padding: '10px 20px',
      borderRadius: '4px',
      cursor: 'pointer',
      fontSize: '16px',
    },
    secondary: {
      backgroundColor: '#6c757d',
      color: 'white',
      border: 'none',
      padding: '10px 20px',
      borderRadius: '4px',
      cursor: 'pointer',
      fontSize: '16px',
    },
  };

  return (
    <button style={styles[variant]} onClick={onClick}>
      {label}
    </button>
  );
}

export default Button;

Enter fullscreen mode Exit fullscreen mode

Now export it from your library's index file:
libs/ui/src/index.ts

export * from './lib/button/button';
export * from './lib/ui';
Enter fullscreen mode Exit fullscreen mode

Step 5: Use the Library in Your App (2 minutes)
Now comes the magic! Let's use our shared Button component in the todo-app.
Open apps/todo-app/src/app/app.tsx and replace its content:

import { Button } from '@my-nx-workspace/ui';
import { useState } from 'react';

export function App() {
  const [count, setCount] = useState(0);

  return (
    <div style={{ padding: '40px', fontFamily: 'Arial, sans-serif' }}>
      <h1>Welcome to Nx Monorepo! 🚀</h1>
      <p>You've clicked the button {count} times</p>

      <div style={{ marginTop: '20px', display: 'flex', gap: '10px' }}>
        <Button 
          label="Increment" 
          variant="primary"
          onClick={() => setCount(count + 1)} 
        />
        <Button 
          label="Reset" 
          variant="secondary"
          onClick={() => setCount(0)} 
        />
      </div>

      <p style={{ marginTop: '30px', color: '#666' }}>
        ✨ This button component is shared from our UI library!
      </p>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Step 6: Run Your App (1 minute)
Time to see it in action:
npx nx serve todo-app
Open your browser to http://localhost:4200 and you should see your app running with the shared button components!

Step 7: Experience the Power of Nx
Visualize Dependencies
Want to see how your projects are connected? Run:
npx nx graph
This opens an interactive dependency graph in your browser. You'll see how todo-app depends on the ui library. Pretty cool, right?
Smart Caching
Try building your app:
npx nx build todo-app
Now run it again:
npx nx build todo-app
Notice how the second build is instant? That's Nx's computation caching at work. It knows nothing changed, so it retrieves the result from cache.

See What's Affected
Make a change to your Button component, then run:
npx nx affected:graph
Nx shows you exactly which projects are affected by your changes. This becomes incredibly powerful when you have dozens of apps and libraries.

What You've Accomplished
In just 10 minutes, you've:

✅ Created an Nx monorepo workspace
✅ Generated a React application
✅ Built a shared UI library
✅ Used the library across your app
✅ Experienced smart caching and dependency tracking

Common Gotchas
Import paths not working? Make sure your tsconfig.base.json has the correct path mappings. Nx should handle this automatically, but it's good to check.
Build errors? Try clearing the Nx cache with npx nx reset
Want to add more frameworks? You can mix React, Angular, Node.js, and more in the same workspace!

Resources:

Nx Documentation
Nx GitHub
Nx Community Slack

Happy coding! 🎉

Top comments (0)