Building An Application With React And Nx

A comprehensive guide to creating modern React applications using Nx monorepo architecture. Learn workspace setup, generators, shared libraries, and best practices.

Building modern web applications requires careful consideration of architecture, tooling, and development workflow. React has established itself as the dominant library for building user interfaces, while Nx provides an extensible build system that enables monorepo development at scale. Together, they form a powerful combination that can accelerate development, improve code quality, and simplify codebase management. By leveraging professional web development services, teams can implement these tools effectively to build scalable applications.

This comprehensive guide explores how to build applications with React and Nx, covering everything from initial workspace setup to advanced patterns for code sharing and testing.

What Is Nx and Why Use It With React?

Nx is a powerful open-source build system developed by Nrwl that provides tools and techniques for enhancing developer productivity, optimizing CI performance, and maintaining code quality. Originally developed by former Angular team members at Google, Nx has evolved to support multiple frameworks including React, Vue, Angular, and Node.js.

The platform offers several key benefits that make it particularly well-suited for React development:

Monorepo Capabilities

Nx enables organizations to manage multiple projects in a single repository, which is especially valuable for React applications that may include multiple frontend apps, shared component libraries, and backend services. This approach promotes code reuse, simplifies dependency management, and provides better visibility across the entire codebase.

Incremental Builds

Nx analyzes the dependency graph and only rebuilds or retests what has changed. This can dramatically reduce build times in large codebases, as unchanged code is pulled from cache rather than being rebuilt from scratch.

Shared Code Libraries

Nx makes it straightforward to create and share code between different applications in the workspace. This is particularly useful for React projects where UI components, utility functions, and TypeScript interfaces may need to be shared across multiple applications.

Consistent Tooling

Nx provides a unified configuration for linting, testing, and building across all projects in the workspace. This ensures consistent code quality standards and reduces the cognitive load of switching between different tool configurations.

Why Combine React and Nx?

Component-Based Architecture

React's component model aligns well with Nx's library generation capabilities for organized code

TypeScript Integration

First-class TypeScript support in both React and Nx ecosystems for type safety

Integrated Testing

Jest and Cypress integrate seamlessly with Nx workspace for comprehensive test coverage

Code Organization

Clear structure separating deployable apps from shared libraries for maintainability

Setting Up Your Nx Workspace

The first step in building an application with React and Nx is creating a new Nx workspace. This workspace will serve as the foundation for your entire project structure.

Creating a New Workspace

npx create-nx-workspace@latest my-react-app --preset=react

This command initializes a new workspace with React pre-configured. The wizard will guide you through several configuration options:

  • Stack Selection: Choose React as your frontend framework (Nx supports multiple frameworks including Angular, Vue, and Next.js)
  • Application Options: Configure whether you want built-in routing, which styling solution to use (CSS, Sass, Tailwind CSS, or CSS-in-JS solutions like styled-components or Emotion), and your preferred bundler (Vite, Webpack, or esbuild)
  • Testing Setup: Select your preferred test runners for unit testing (Jest or Vitest) and E2E testing (Cypress or Playwright)

Workspace Structure

my-app/
├── apps/ # Deployable applications
│ ├── web-app/ # Main React application
│ └── web-app-e2e/ # E2E tests
├── libs/ # Shared libraries
│ ├── ui/ # UI component library
│ ├── utils/ # Utility functions
│ └── data-access/ # API and data fetching logic
├── tools/ # Workspace tooling and generators
├── nx.json # Nx configuration
├── tsconfig.base.json # TypeScript base configuration
└── package.json # Workspace dependencies

This structure separates deployable applications from shared libraries, making it clear which parts of your codebase are application-specific versus reusable.

Creating React Applications with Nx Generators

Nx generators are a powerful tool for scaffolding code in your workspace. The React plugin provides generators for creating applications, components, libraries, and more.

Generating a New React Application

nx g @nx/react:app my-new-app

This command creates a new application at apps/my-new-app with all necessary configuration files, source directories, and entry points.

Component Generation

# Generate a new component
nx g @nx/react:component my-component --project=my-app

# Generate a component in a specific directory
nx g @nx/react:component features/user-profile --project=my-app

Components generated with Nx follow best practices for file structure and TypeScript configuration, and are automatically included in the project's tsconfig files.

Library Generation

# Generate a UI component library
nx g @nx/react:lib ui-components

# Generate a utility library
nx g @nx/js:lib utils --bundler=tsc

Libraries are not directly deployable but can be imported by applications and other libraries in the workspace. Nx generators create libraries with proper TypeScript configuration and import paths pre-configured.

Creating Shared Libraries

One of the most powerful features of Nx is the ability to easily share code between different applications in your workspace. This is particularly valuable for React applications that need to share UI components, types, or utility functions.

TypeScript Interfaces and Models

Sharing TypeScript interfaces between frontend and backend is a common pattern that improves type safety:

// libs/shared-types/src/lib/user.ts
export interface User {
 id: string;
 name: string;
 email: string;
 role: 'admin' | 'user' | 'guest';
}

Both your React frontend and Node.js backend can import this interface:

// Frontend (React)
import { User } from '@my-org/shared-types';

// Backend (Express/Node.js)
import { User } from '@my-org/shared-types';

This ensures that the frontend and backend agree on data structures without code duplication.

Component Libraries

React component libraries can be shared across multiple applications:

nx g @nx/react:lib design-system --directory=libs/ui/design-system

Components in this library should be well-documented and tested, as they will be used throughout your application portfolio. Consider using Storybook for component documentation:

nx g @nx/react:storybook-configuration design-system

This generates a Storybook setup for your component library, making it easy to develop and document components in isolation.

Testing Strategies

Nx provides integrated testing support for unit tests, integration tests, and E2E tests across all projects in your workspace. Implementing comprehensive testing practices is essential for maintaining code quality in production applications, and teams can benefit from AI automation services to streamline their CI/CD pipelines.

Unit Testing with Jest and Vitest

React applications generated with Nx come pre-configured for testing with Jest or Vitest:

# Run all unit tests
nx test web-app

# Run tests in watch mode
nx test web-app --watch

# Run tests for affected projects
nx affected:test

Test files should follow the naming convention *.spec.tsx or *.test.tsx and can be placed alongside the components they test.

E2E Testing with Playwright and Cypress

Generate and run E2E tests for your React application:

# Generate E2E project
nx g @nx/playwright:configuration web-app

# Run E2E tests
nx e2e web-app-e2e

Nx creates a separate E2E project that uses Playwright or Cypress to test your application in a browser. These tests verify user flows and interactions across your entire application.

Affected Commands

One of Nx's most powerful features is the ability to identify and operate on only the projects affected by recent changes:

# Build only projects affected by recent changes
nx affected:build

# Run tests for affected projects
nx affected:test

# Lint affected projects
nx affected:lint

Nx analyzes your project's dependency graph and compares it against the git diff to determine exactly which projects have changed. This dramatically reduces CI time for large codebases.

Best Practices and Recommendations

Based on the patterns and practices from official documentation and experienced practitioners, here are key recommendations for building React applications with Nx.

Start Simple, Organize Later

Begin with a simple workspace structure and organize into libraries as patterns emerge. Avoid over-engineering upfront by creating libraries for code that doesn't yet need to be shared.

Consistent Code Style

Use Nx's ESLint configuration to enforce code quality across all projects:

nx lint web-app
nx run-many -t lint --all

Configure .prettierrc at the workspace root to ensure consistent formatting across all your TypeScript projects. Clean, consistent code is essential not only for maintainability but also for SEO performance, as search engines favor well-structured, fast-loading code.

Leverage Affected Commands

Use nx affected:* commands in CI/CD to only run tests and builds for changed projects. This dramatically reduces CI time for large codebases and improves developer productivity.

Automate Generator Usage

Make generator usage a habit for all new code. This ensures consistent structure and saves time on boilerplate:

  • Use component generators for all new React components
  • Use library generators for new shared code
  • Configure workspace generators for custom scaffolding needs

Migrating Existing React Apps to Nx

If you have an existing React application, you can incrementally adopt Nx without rewriting everything:

  1. Install Nx: npm install -D nx
  2. Create Workspace Configuration: npx nx init
  3. Move Your Application: Move your existing application into the apps/ directory
  4. Add Dependencies: Install the React plugin (npm install -D @nx/react)
  5. Create Shared Libraries: Identify code that should be shared and create libraries using Nx generators

This incremental approach allows teams to adopt Nx without a big-bang migration, reducing risk and allowing for learning along the way.

Frequently Asked Questions

Ready to Build Modern React Applications?

Our team specializes in building scalable React applications using modern tooling like Nx. Let's discuss how we can help your project.