Group tasks
Name a set of tasks once and run them with one word.

A check that means lint, typecheck and test is a task with dependsOn and no command. Running it runs its members, in parallel where the graph allows.
Groups compose like any task: depend on one, filter it, run it with --all. An empty dependsOn: [] is a named no-op, handy as a placeholder a project can fill in later.
// config
// packages/web/vx.config.ts
import { defineProject } from '@vzn/vx/config'
export default defineProject({
tasks: {
lint: { exec: { command: 'oxlint' } },
test: { exec: { command: 'vitest run' } },
check: { dependsOn: ['lint', 'test'] },
},
})More in Run what you mean

Run just the task
Skip the dependency chain when you know it is already built.

Timeouts
A hung task is killed and reported as a timeout, not left to stall the run.

Pass arguments through
Arguments after -- reach the task, and the cache keeps each set apart.

Source-only packages still count
A package with no build step still moves its dependants’ cache keys when its files change.

Say what a task needs
One short syntax for upstream, cross-project and pattern edges.

A typo never runs half the graph
Ask for a task no project has and vx stops before anything starts.

Filter by tag
Tag projects once, then run a task across every project with that tag.

Filter by folder
Pick projects by where they live, or the root project alone.

Remote pools at their own width
Send work to a remote pool and vx fills the pool, not your laptop’s core count.

Runs take turns
Two runs in one checkout wait for each other instead of fighting over files.