Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nrwl/nx/llms.txt

Use this file to discover all available pages before exploring further.

Nx provides a layered approach to CI optimisation. You can start with just running tasks on affected projects, then add remote caching, and finally add distributed agents — adopting each layer incrementally.

Connect to Nx Cloud

All remote features (caching and distribution) require connecting your workspace to Nx Cloud.
npx nx@latest connect
This command:
  • Creates a workspace on Nx Cloud
  • Writes your NX_CLOUD_ACCESS_TOKEN to .env.local (gitignored)
  • Adds nxCloudId to nx.json
Never commit NX_CLOUD_ACCESS_TOKEN to source control. Add it as a secret in your CI provider’s environment variable settings.

Remote caching (Nx Replay)

Once connected, remote caching is enabled automatically. Any task result — terminal output plus build artifacts — that a CI run or team member computes is stored in Nx Cloud. Subsequent runs that match the same input hash restore from cache instead of re-running the task. What gets cached:
  • Terminal output (logs, warnings, errors)
  • Output files declared in each task’s outputs configuration
  • The input hash used to identify the cache entry
Caching is zero-config after connecting. For cache correctness, ensure tasks declare accurate inputs and outputs in project.json or nx.json.

Run only affected tasks

Use nx affected on CI to limit work to projects touched by a pull request.
nx affected -t lint test build
Nx uses Git history to find changed files and walks the project graph to identify all downstream dependants. You can visualise what will be selected:
nx graph --affected
In CI you must set explicit base and head SHAs. Nx reads the NX_BASE and NX_HEAD environment variables:
NX_BASE=origin/main~1
NX_HEAD=origin/main
Alternatively pass them as flags:
nx affected -t build --base=origin/main --head=$PR_BRANCH_NAME
The recommended base SHA is the last successful commit on main so that every change since the previous green build is covered.

Generate a CI workflow

Nx can scaffold a complete CI configuration for your provider:
nx g @nx/workspace:ci-workflow --ci=github

GitHub Actions example

name: CI

on:
  push:
    branches:
      - main
  pull_request:

jobs:
  main:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          filter: tree:0

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - run: npm ci

      - run: npx nx affected -t lint test build
        env:
          NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
fetch-depth: 0 is required so that Nx has access to the full Git history needed to compute affected projects. filter: tree:0 speeds up the shallow-to-full checkout.

GitLab CI example

image: node:20

variables:
  NX_CLOUD_ACCESS_TOKEN: $NX_CLOUD_ACCESS_TOKEN

cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - node_modules/

before_script:
  - npm ci

nx-affected:
  script:
    - |
      export NX_BASE=$(git merge-base origin/main $CI_COMMIT_SHA)
      export NX_HEAD=$CI_COMMIT_SHA
      npx nx affected -t lint test build
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

Nx Agents for distributed task execution

When affected runs are still too slow — for example when a widely-used library changes — you can distribute tasks across multiple agent machines using Nx Agents. Add the start-ci-run command before your task invocations:
- run: npx nx-cloud start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="build"
This tells Nx Cloud to:
  1. Spin up 3 linux-medium-js agents
  2. Collect every nx command that runs in the pipeline
  3. Distribute tasks across agents based on historical run times and task dependencies
  4. Replay all logs and artifacts back to the main job
The --stop-agents-after flag names the last target in your pipeline. Agents shut down automatically once all tasks of that target are complete.

Dynamic agent allocation

Scale the number of agents based on PR size by creating a distribution config:
.nx/workflows/distribution-config.yaml
distribute-on:
  small-changeset: 3 linux-medium-js
  medium-changeset: 6 linux-medium-js
  large-changeset: 10 linux-medium-js
Nx Cloud calculates the ratio of affected projects to total projects and selects the matching changeset. Reference the file instead of an inline string:
- run: npx nx-cloud start-ci-run --distribute-on=".nx/workflows/distribution-config.yaml" --stop-agents-after="build"

Full GitHub Actions workflow with agents

name: CI

on:
  push:
    branches:
      - main
  pull_request:

jobs:
  main:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          filter: tree:0

      - run: npx nx-cloud start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="build"

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - run: npm ci

      - run: npx nx affected -t lint test build
        env:
          NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}

Environment variables reference

VariablePurpose
NX_CLOUD_ACCESS_TOKENAuthenticates the workspace with Nx Cloud. Set as a CI secret.
NX_BASEBase Git SHA for affected calculation.
NX_HEADHead Git SHA for affected calculation.
NX_DAEMONSet to false to disable the Nx daemon (disabled by default in CI).
NX_PROFILEPath to write a performance profile JSON file.

How affected, caching, and agents combine

1

nx affected narrows the task set

Only projects touched by the PR (and their dependants) are considered, discarding unrelated work entirely.
2

Remote caching eliminates redundant computation

Tasks whose inputs haven’t changed since the last run are restored from the Nx Cloud cache — no re-execution needed.
3

Nx Agents parallelize what remains

Remaining tasks are distributed across agent machines. Each task runs once; its output is shared via the remote cache.

Build docs developers (and LLMs) love