Skip to content

Think of Nx as a coordinator for the tools in your workspace. Vite, Jest, and other tools still do their own work, while Nx maps how projects and tasks relate and then decides what to run, in what order, and whether previous work can be reused.

The project graph represents projects in your workspace and the dependencies between them. It also includes external dependencies, such as Vite, React, and Angular.

A project graph with applications and libraries

Nx plugins identify projects from files such as package.json, project.json, and tool configuration files. Nx then analyzes source code, TypeScript configuration, and package dependencies to find the connections between projects. You can add dependencies manually when Nx can't determine them from the workspace.

Nx caches the project graph and recomputes the parts affected by file changes. The updated graph reflects the current state of your workspace.

The project graph after a change

Nx combines project configuration with metadata inferred by plugins. For example, the @nx/vite plugin can infer tasks from a project's vite.config.ts file, including commands, cache inputs, and outputs.

Nx, Nx Console, coding agents, and other integrations use this metadata to understand and interact with your workspace.

Tools using Nx metadata

Nx creates a task graph whenever you run tasks. Each node is a task, which is a specific target invoked for a project, such as myapp:build. Edges represent the dependencies between tasks. For example, nx test lib creates a task graph with one node:

Task graph for nx test lib
Loading...

The project graph and task graph aren't identical. In this project graph, both applications depend on lib:

Project dependencies
Loading...

Running nx run-many -t test -p app1 app2 lib creates three independent tasks because the task pipeline doesn't define dependencies between the test targets:

Independent test tasks
Loading...

Without task dependencies, Nx can run all three test tasks in parallel.

Builds commonly need a different relationship because an application may consume the built output of its libraries. Use dependsOn to make each build task depend on the build tasks of its project dependencies:

{
"targetDefaults": {
"build": {
"dependsOn": ["^build"],
},
},
}

Running nx run-many -t build -p app1 app2 lib now produces task dependencies that follow the project graph:

Build tasks with dependencies
Loading...

With this rule, app1:build and app2:build wait for lib:build. After lib:build completes, Nx can run both application builds in parallel.

Tasks running in dependency order and in parallel

For more information, see task pipeline configuration.

Running nx test app1 creates the app1:test task and any tasks it depends on. Running nx run-many -t test -p app1 lib creates tasks for both projects. Without a project filter, nx run-many -t test creates a test task for every project with that target.

Use nx affected -t test to limit the task graph to projects affected by your changes. Nx maps changed files to projects, applies plugin-specific change analysis, and follows the project graph to include dependent projects. It then runs the requested target for that set.

For example, if a change affects lib, and both app1 and app2 depend on it, the affected project set contains all three projects.

Affected projects after a library change

For more information, see affected tasks.

Before running a cacheable task, Nx hashes its inputs. These inputs can include source files, configuration, dependencies, runtime values, and command-line arguments. If the hash matches a previous run, Nx restores the cached terminal output and file artifacts instead of running the task again.

Inputs used to calculate a task hash

Nx checks the local cache first and then checks the remote cache when one is configured. A cache hit has the same result as executing the task, but avoids the computation.

Nx checking local and remote caches

For the complete hashing and cache model, see how caching works.

A single machine eventually limits how many tasks you can run in parallel. Nx Agents distribute the task graph across multiple machines while preserving its dependency order. Agents use remote caching to share task artifacts, so a dependent task can use output produced on a different machine.

A task graph distributed across agent machines