Skip to content
TilloTech Docs

Nx task execution and cache

EOS uses Nx to execute package scripts and repository tasks.

Tool responsibilities

ToolResponsibilityExamples
miseInstall and select repository tool versionsmise install
pnpmInstall dependencies, manage workspaces, and maintain the lockfilepnpm install, pnpm --filter @tillo/scout add <package>
NxSelect project tasks, run their declared dependencies, and manage the task cachenx run @tillo/scout:test, nx affected -t test
UltraciteCheck and fix source files with the Oxlint and Oxfmt presetsnx run eos:lint, nx run eos:fmt

mise.toml pins the tool versions. package.json and pnpm-lock.yaml define the repository's local Nx dependency. The mise-installed Nx launcher uses that local version. An Nx upgrade updates both declarations together.

Mise package task inference is disabled. The repository has one project task interface through Nx. The repository no longer installs the ni and nr aliases.

Commands

These commands assume a complete setup with mise install and an active mise shell. Mise installs Nx 23.2.1 through its npm backend. The Nx launcher uses the repository's local Nx version for task execution.

CommandScope
nx run-many -t build typecheck test test:e2e lint fmt:checkAll build, typecheck, E2E, test, lint, and format-check targets
nx run @eos/docs:buildThe docs build and its declared dependencies
nx affected -t test test:e2e --base=origin/main --head=HEADUnit, functional, and E2E tests for changed projects
nx graphThe project graph
nx show target inputs @eos/plugin-tests:testResolved inputs for the shared plugin tests
nx resetClear local Nx state and cache

The affected example uses the local origin/main ref. Nx does not fetch it.

Root aliases such as pnpm build, pnpm test, and pnpm check call Nx for compatibility. They use the same task graph and cache as direct Nx commands.

Direct workspace commands such as pnpm --filter @tillo/scout test execute the package script without the Nx dependency graph or task cache. Scout package test scripts require an existing build. The standard project task commands use Nx.

Repository maintenance commands remain pnpm scripts. Examples include pnpm registry:login and pnpm changeset. The finalise-change guide uses nx affected with the complete verification target set. Direct CLI commands use pnpm when the CLI belongs to a workspace dependency, such as pnpm exec wrangler from the Figma MCP directory.

Ultracite uses one root configuration for the monorepo. The eos project maps the root check and fix scripts to Nx targets. Packages do not define duplicate lint or format scripts. The configuration follows the Oxlint migration guide. The pre-commit hook applies Ultracite fixes to supported staged files. Lefthook then runs the affected Nx checks. See the Git hook guide.

Task configuration

nx.json defines shared inputs and task defaults. Each project.json defines workspace exceptions. Package scripts remain the executable commands.

The root excludes its package scripts from Nx task inference to prevent recursive task execution. Explicit targets on the eos project provide the root lint and format tasks.

ProjectTargetCheck
eos-apmapm:auditCurrent tracked and untracked local APM files
eos-documentationdocs:checkDepends on Markdown format, lint, and offline links
eos-documentationdocs:format:check, docs:lint, docs:linksIndividual documentation checks
eos-scriptstest:scriptsRepository script and Nx configuration tests
eos-releasechangeset:statusChangesets release metadata
eoslint, lint:all, fmt:check, fmtUltracite source check and fix for the monorepo
@eos/plugin-testsdocs:skills:checkGenerated marketplace skills reference

The marketplace reference, repository lint, repository format, Markdown lint, and Markdown format checks use the cache. The other repository checks do not. The Changesets target runs changeset status when metadata files exist. Otherwise, it reports that no files need validation. The changesets skill still assesses release impact. The status command depends on Git state and the local main ref. APM audits use the mise-installed APM version and skip deleted files. Nx calls the check tools directly. Lefthook passes staged or pushed filenames to Nx through --stdin. Nx owns task selection and parallel execution. The tools read their existing exclusions and include untracked source files.

Nx selects projects, then their requested targets. Target inputs determine cache validity and can mark a project affected by shared files. They do not select individual targets within an affected project. Documentation-only and test-only changes can select all requested workspace targets. The former finalise-change command applied narrower rules.

The eos:lint target uses NX_BASE and NX_HEAD when CI supplies them. The Git hook supplies its staged paths through the Nx process. The target passes these paths to Ultracite. It checks the full repository when no path scope is available or when a shared Ultracite input changes. The affected target does not use the cache because its path scope can change. Use eos:lint:all for an explicit cached full check.

Build, test, typecheck, full lint, and format-check targets use the local cache. Build, test, typecheck, and mutation targets require dependency builds. Incremental mutation targets use the local cache. Full mutation targets do not use the cache. Nx runs one mutation target at a time on each machine. Format commands change files and do not use the cache.

Development and preview targets are continuous and uncached. The docs build also remains uncached because it reads external documentation sources.

Inputs and outputs

Shared inputs include package and tool configuration, the pnpm lockfile, the Node.js version, and root Ultracite configuration. Workspace inputs also include declared dependency inputs. Mutation inputs include project files, dependency production files, and the shared baseline helper.

The shared plugin tests include child plugin files and documentation. Each child plugin has an explicit dependency relationship with the test workspace. Harbourmaster tests include the root workflows and shared scripts that they read.

Build targets restore their declared output directories. Scout tests also restore dist, because their package script builds the CLI. Figma MCP tests restore coverage output. Incremental mutation targets restore the Stryker state and mutation reports from the local Nx cache.

CI cache

CI installs Node.js and pnpm through the setup action. It uses pnpm exec nx to select the repository's local Nx binary. This prefix does not add another task runner. Local shells use the Nx launcher that mise installs.

Build, typecheck, lint, test, and mutation jobs use nx affected. Each job fetches the full Git history. nrwl/nx-set-shas@v5 selects the base and head from GitHub workflow history. The action fails if it cannot find a successful base workflow. Its GitHub API access does not require Nx Cloud. Repository script tests run on every CI execution.

The mutation job restores trusted Stryker reports before Nx starts the affected targets. Pull requests can read the main reports. Only successful main and scheduled jobs publish new reports. The scheduled workflow uses nx run-many to refresh all full mutation targets.

Each CI job uses its own local Nx cache. Jobs do not share Nx artifacts across machines or workflow runs. The pnpm dependency cache and Stryker baseline artifacts remain separate.

The setup action does not start a Turbo cache server or require cache secrets. Fork pull requests use the same local cache behaviour as other jobs.

Remote cache configuration remains separate work. The former R2 resources and secrets remain available for rollback but current workflows do not use them. Nx Cloud is disabled in this configuration. Nx analytics is also disabled.

Migration reference

The Nx migration guide describes the configuration conversion. Nx deprecated its former S3 cache package. See the self-hosted cache notice.