NX Monorepo Primer
What is NX?
NX is a build system and set of extensible dev tools for monorepos, designed to help maintain, test, build, and scale JavaScript/TypeScript applications. In the v4-monorepo, NX manages dependencies between projects, optimizes build and test processes, and provides a consistent workflow across multiple applications and libraries.
Key Concepts
Project Graph
NX automatically creates a dependency graph of all projects in the workspace, which it uses to:
- Determine the order in which to build projects
- Only build what's necessary when making changes
- Visualize project relationships
To see the project graph in this repository:
Workspaces and Projects
- Workspace: The entire monorepo
- Projects: Individual applications or libraries within the monorepo
- In v4-monorepo, projects are defined in the
apps/
andlibs/
directories - Each project has a
project.json
file defining its configuration
To list all projects:
Targets
Targets are operations that can be performed on projects (like build, test, lint). They're defined in each project's project.json
file.
To see all targets for a project:
Executors
Executors are plugins that know how to run specific targets. For example, the @nx/jest:jest
executor knows how to run Jest tests.
Affected Commands
One of NX's most powerful features is the ability to run commands only on projects affected by changes:
# Only build projects affected by changes
nx affected -t build
# Only test projects affected by changes
nx affected -t test
Caching
NX caches the results of commands to avoid unnecessary rebuilds, greatly speeding up development and CI workflows.
How NX is Used in This Repository
In the v4-monorepo:
-
Project Organization:
-
TypeScript applications in
apps/
(e.g., orderbook, datastream) - Python applications also in
apps/
(e.g., funding, poseidon) -
Shared libraries in
libs/
(e.g., commons-ts, connections-ts) -
Configuration:
-
nx.json
: Main NX configuration project.json
: Per-project configuration-
Projects are tagged by language and type for easier filtering
-
Standardized Targets:
build
: Compile and package the projecttest
: Run unit testslint
: Check code qualityformat
: Format codevalidate
: Run all checks (lint, test, build)
Common NX Commands
Basic Commands
# Build a specific project
nx build orderbook
# Test a specific project
nx test commons-ts
# Run a specific target
nx run orderbook:lint
Advanced Commands
# Run a target on all projects
nx run-many -t build
# Run a target on projects with specific tags
nx run-many -t test --projects=tag:language:typescript
# Visualize the dependency graph
nx graph
# Clear the cache
nx reset
Project-Specific Configuration
Each project in the v4-monorepo has its own project.json
file that defines:
- The project type (application or library)
- Source code location
- Dependencies on other projects
- Available targets and how to run them
- Custom configuration options
Example structure of a project.json
file:
{
"name": "orderbook",
"projectType": "application",
"sourceRoot": "apps/orderbook/src",
"tags": ["language:typescript", "type:application"],
"targets": {
"build": {
/* build configuration */
},
"test": {
/* test configuration */
},
"lint": {
/* lint configuration */
}
// other targets...
}
}
Troubleshooting NX
Common Issues
Issue | Solution |
---|---|
"Cannot read properties of null (reading 'unlock')" | Run nx reset to clear NX cache |
"Project not found" | Check project name with nx show projects |
"Target not found" | Check targets with nx show project <name> --targets |
"Build fails with out of memory error" | Use nx run <project>:build:retry which allocates more memory |
"Cannot resolve dependency" | Check the project graph with nx graph |