Tasks
A task is one shell command in a project’s vx.config.ts. dependsOn
says what must finish first; vx runs the rest in parallel.
import { defineProject } from '@vzn/vx/config'
export default defineProject({ tasks: { codegen: { exec: { command: 'graphql-codegen' }, inputs: { files: ['schema.graphql'] }, cache: { outputs: { files: ['src/gen/**'] } }, }, build: { description: 'compile TypeScript to dist/', dependsOn: ['codegen', '^build'], exec: { command: 'tsc -b' }, // codegen's output reaches this key through codegen's own key; a key // that read it could not be known until codegen ran, so vx refuses it. inputs: { files: ['src/**', '!src/gen/**'] }, cache: { outputs: { files: ['dist/**'] } }, }, e2e: { dependsOn: ['build', 'api#build'], exec: { command: 'playwright test', timeout: '10m', retries: 1 }, }, // A group: no command, it only runs its dependencies. ci: { dependsOn: ['build', 'e2e'] }, },})flowchart LR codegen --> build ubuild["ui#build"] -->|^build| build build --> e2e apibuild["api#build"] --> e2e build --> ci e2e --> ci
dependsOn
Section titled “dependsOn”dependsOn |
Runs first |
|---|---|
'build' |
build in this package |
'^build' |
build in each package this one depends on (a lockfile plugin’s edges) |
'api#build' |
build in the api package |
'build.*' |
every task in this package whose name matches |
A task-name pattern is allowed: dependsOn: ['build.*'], or '^build.*'.
Bare wildcards and negation (*, !task) are not.
A cycle or a missing 'pkg#task' is an error.
Groups
Section titled “Groups”A task with no exec is a group: it only runs its dependencies.
ci: { dependsOn: ['build', 'e2e'] },When a task fails
Section titled “When a task fails”| Flag | vx |
|---|---|
--continue=deps-ok (default) |
skips its transitive dependents and runs the rest |
--continue=never |
stops at the first failure |
--continue=always |
runs the dependents, but saves none of them |
vx run test --all --continue=neverExplore your graph
Section titled “Explore your graph”See what each task waits on and what waits on it, in your own repo:
vx run build --all --dry=json > plan.jsonDrop plan.json below, or paste it, then type a task. Nothing is uploaded.
Run vx run build --all --dry=json > plan.json in your repo. With JavaScript on, paste it here to browse what each task waits on and why.
Every exec field
| Field | Does |
|---|---|
exec.command |
the one shell command, run in the package’s directory (chain steps with &&) |
exec.env |
what the command sees (Environment variables) |
exec.timeout |
kill the task after this long |
exec.retries |
re-run a failed task this many times |
exec.persistent |
a server or watcher that does not exit (Dev servers) |
exec.sandbox |
only the declared files and network (Sandboxing) |
exec.interactive |
reads the terminal: a prompt, a REPL, a TUI; runs alone, never cached |
exec.platforms |
the machines it runs on, such as ['darwin-arm64']; elsewhere skipped, on CI refused |
exec.remote |
false keeps it here; 'only' for a remote pool (Remote execution) |
exec.remote is the one exec field stripped from the key: where a task
ran says nothing about what it made. The rest is in the key, description
included, so editing a description costs one re-run.
See Caching to skip a task whose inputs did not change, and vx.config.ts for every field.