Skip to content
GitHubRSS

Glossary

Every task runner solves the same handful of problems, and each one names them differently. This page defines each idea once, without reference to any tool, then gives the name vx, Turborepo, Nx and Bazel use for it. Compare tools by what they do, not by what they call it.

The other tools’ names were checked against their own documentation on 2026-09-24, and each is linked. A dash means that tool’s documentation has no term for the idea. It does not mean the tool cannot do the thing some other way.

The repository as a unit of work: every project in it, their relationships, and the settings that apply to all of them. A workspace is what a single command operates over.

One buildable unit inside the workspace, usually a package with its own package.json. Projects depend on each other the way packages do.

One command run for one project: build ui, test api. The task is the unit a runner schedules, caches and reports on.

  • vx: a task, id project#task, declared under tasks (schema)
  • Turborepo: a task, declared under tasks in turbo.json (configuration)
  • Nx: a task, an invocation of a target on a project (glossary)
  • Bazel: an action, produced from a target by its rule

An edge saying one task must finish before another starts, because the second reads what the first produced. The common case is “build my dependencies first”, written as the same task in every project this one depends on.

Every task a command will run, with the dependency edges between them. The runner derives it from the project graph and the task dependencies, then schedules it. It is the thing to read when a run does something surprising.

The projects and the dependencies between them, read from the package manager’s manifests. The task graph is built on top of it.

The projects a change can reach: those whose files changed, plus everything that depends on them. Running only the affected tasks is how a large repository keeps CI proportional to the change.

Everything that can change a task’s result: its source files, its configuration, the environment variables it reads, and the results of the tasks it depends on. A runner can have you declare them, or infer them, and the choice decides what it can prove.

The files a task produces, which a cache stores and restores. Terminal output is usually stored too, so a replayed task prints what it printed.

A digest of a task’s inputs. Two runs with the same key are expected to produce the same outputs, so the second can replay the first. Everything that decides the key decides what the cache can be trusted with.

  • vx: the cache key, a 16-hex xxHash3 digest (caching)
  • Turborepo: the hash, or “fingerprint” (caching)
  • Nx: the hash of the cache inputs (glossary)
  • Bazel: the action key

A hit finds the key in the cache and replays the stored outputs instead of running the task. A miss runs it. A stale hit is a hit whose stored outputs are wrong for today’s inputs, because something the task read was never part of the key. It reports success and serves yesterday’s result, which makes it the worst failure a cache can have.

A cache shared between machines, so CI and every developer reuse each other’s results. It makes the cost of a stale hit shared too.

  • vx: a remote CacheLayer from a plugin, such as @vzn/vx-reapi or turboCache() (remote caching)
  • Turborepo: Remote Caching (remote caching)
  • Nx: remote cache (glossary), offered as Nx Replay
  • Bazel: remote caching, with a local disk cache

A task is hermetic when it reads only its declared inputs and writes only its declared outputs. A sandbox enforces that by running the task where undeclared files cannot be reached, and reporting what it tried. A sandbox is how a runner proves the key is complete, rather than trusting it.

Running a task on another machine and bringing its outputs back, so a laptop can use a build farm. It needs every input declared, because the other machine sees nothing else.

  • vx: exec.remote, through the @vzn/vx-reapi plugin (remote execution)
  • Turborepo: —
  • Nx: distributed task execution, which spreads tasks across CI agents (glossary)
  • Bazel: remote execution, whose protocol (REAPI) the vx plugin speaks

A task that does not exit, such as a dev server or a watcher. A runner cannot wait for it to finish before starting what depends on it, and it must never be cached.

  • vx: exec.persistent, ready when its output matches readyWhen (dev tasks)
  • Turborepo: persistent: true (configuration)
  • Nx: a continuous task, continuous: true
  • Bazel: —

The longest chain of dependent work in the task graph. No amount of parallelism finishes a run faster than its critical path. A scheduler that starts the tasks on it first finishes sooner on the same machine.

  • vx: with no plugin the scheduler orders ready tasks by how many tasks wait on each; @vzn/vx-schedule-history orders them by remaining critical path, learned from past runs (What a run does)
  • Turborepo: —
  • Nx: the critical path, named where its CI guide says what a cache cannot fix (CI caching)
  • Bazel: the critical path, which every build reports and the profiler draws (JSON trace profile)

A seam is a point in the pipeline where outside code decides. Examples are where a task runs, where artifacts live, who observes the run, and how the graph is shaped. A plugin fills one or more seams. The width of the seams decides what can be built on a tool without forking it.