A Raid command is a named sequence of tasks. Once defined, it's available as a first-class raid <name> subcommand — auto-listed in raid --help, invocable from anywhere on disk, and runnable in CI without changes.
This guide walks through writing one from scratch and tours the eleven built-in task types.
1. The minimum command
A command has a name, an optional usage: line for --help, and a tasks: array. The smallest useful one is one task long:
commands:
- name: dev
usage: Run the dev server with hot reload
tasks:
- type: Shell
cmd: npm run dev
Run it from anywhere:
raid dev
Raid resolves the command, switches to the repo's directory, and runs the task.
2. Where to define them
Commands can live at two levels:
- Profile-level (in
*.raid.yaml) — show up as platform-wide commands. Ideal for things every developer should be able to run. - Repo-level (in
raid.yamlinside a repo) — show up the same way; specific to that repo.
When both define the same name, the profile wins. That keeps platform-level commands stable even when individual repos drift.
3. Tour: the eleven task types
Every task has a type:, and Raid ships with eleven of them. All accept an optional name: (shown in output), concurrent: true (run alongside the next task), and a condition: block (skip unless platform/file/command matches).
Shell
Run a shell command. The workhorse:
- type: Shell
cmd: npm test
shell: bash # optional: bash | sh | zsh | powershell | pwsh | cmd
path: ./packages/api # optional: working directory
Script
Run a script file. Pick the runner explicitly:
- type: Script
path: ./scripts/deploy.sh
runner: bash # bash | sh | zsh | python | python3 | node | powershell
Set
Set a variable for later tasks (with $VAR / ${VAR} expansion):
- type: Set
var: VERSION
value: $(git rev-parse --short HEAD)
default: dev # used if value expansion yields empty
Git
A typed wrapper over common git operations — easier to read in YAML than a Shell task:
- type: Git
op: pull # pull | checkout | fetch | reset
branch: main
path: ./
HTTP
Download a file:
- type: HTTP
url: https://example.com/seed.sql
dest: ./data/seed.sql
Wait
Wait for a TCP port or an HTTP endpoint to become healthy:
- type: Wait
url: http://localhost:8080/health
timeout: 60s
Works with bare host:port too — useful for waiting on a database to accept connections.
Template
Render a template file with variable expansion and write the output:
- type: Template
src: ./templates/config.tmpl
dest: ./config/local.yaml
Prompt
Ask the user for a value, store it in a variable:
- type: Prompt
var: ENVIRONMENT
message: Which environment?
default: local
In headless mode (--yes, --headless, RAID_HEADLESS=1, or --json), the default: is used. Without one, the task fails with a clear error — see How to wire Raid into CI.
Confirm
Pause for a y/yes:
- type: Confirm
message: Deploy to production?
Auto-accepts in headless mode.
Print to the terminal — handy for status updates and section dividers:
- type: Print
message: Build complete.
color: green # red | green | yellow | blue | cyan | white
Group
Group several tasks together — useful for retry / parallelism semantics on a logical unit:
- type: Group
ref: build-and-test
parallel: false
attempts: 3
delay: 5s
Group references a named block defined elsewhere — see the Raid technical deep dive for the longer pattern.
4. Composing a real command
Most useful commands chain a few task types together. Example: a release command that prompts for a version, builds, waits for tests to settle, and prints a summary.
commands:
- name: release
usage: Cut a new release of the API
tasks:
- type: Prompt
var: VERSION
message: Version to release (e.g. 1.4.0)?
- type: Shell
cmd: npm run build
- type: Shell
cmd: npm test
- type: Wait
url: http://localhost:8080/health
timeout: 30s
- type: Print
message: Release ${VERSION} built and tested.
color: green
raid release walks the tasks top-to-bottom, halting on the first failure (unless a task opts into options.continueOnFailure: true).
5. Useful options on every task
Each task supports a few optional knobs that aren't a type: value:
name:— friendly label for output (defaults to the type)options.showExeTime: true— print elapsed time after the taskoptions.continueOnFailure: true— log the failure but don't halt the commandconcurrent: true— run alongside the next task instead of sequentially (see How to run tasks in parallel)condition:— skip the task unless a platform / file / command matches:- type: Shell cmd: brew install jq condition: platform: darwin
6. Verify it landed
After saving, your command shows up automatically:
raid --help
The new entry appears alongside the built-ins under user-defined commands.
Next steps
- How to Run Tasks in Parallel with Raid — when and why to use
concurrent. - How to Use Templates and Prompts in Raid Tasks — interactive flows in detail.
- How to Debug a Failing Raid Task — exit codes, verbose mode, common pitfalls.