Skip to content
arrowdocs
v0.3.2/open source · MIT/builds, jobs, pipelines

arrow is a small,fast command runner.

One binary. One config file. Reusable jobs, with parallel runs, local caching, and pluggable steps. No daemon, no service, no surprises - just a sharp little tool that runs your commands and gets out of the way.

~/projects/demo — zsh
# macOS, Linux, Windows — needs nothing else$ curl -fsSL https://arrow.run/install | sh # or with homebrew$ brew install arrow # verify$ arrow --version› arrow 0.3.2 (a4f9c12)
Install with one command. Works on macOS, Linux, Windows.
v0.3.2 · 8.4 MB · single static binary
ships for darwin/arm64, linux/amd64, windows/x64

§ 01 — what it is

A scriptable build runner that doesn't pretend to be a framework.

Fast by default
Starts in under 30 ms. Caches by content hash, parallelises by default, and stays out of your way when you press up-arrow.
One binary, one config
A single arrow.toml file declares jobs, tasks, and environments. No daemon, no service, no hidden side effects, no YAML 47 levels deep.
Pluggable steps
Steps are normal commands. Mix your own with arrow plugins - shell, docker, ssh, change feeds. Compose them like Lego bricks, run them like recipes.

§ 02 — at a glance

Define once. Run anywhere.

A job is a named sequence of steps. Each step is a command, with a working directory, an environment, and an optional cache key. arrow reads them, hashes them, builds a DAG, and runs the rows that are actually out of date.

You wire it up in a single arrow.toml, commit it, and from then on the same arrow run works on your laptop, in CI, and in a friend's machine in another timezone.

No central server is required. arrow keeps a local cache in ~/.arrow/cache and a config in ./arrow.toml - that's the entire surface area.

arrow.toml
# arrow.toml — a tiny buildable job[project]name = "demo"version = "0.3.2" [jobs.build]description = "compile, bundle, write to ./dist"steps = [  { name = "lint",    run = "pnpm lint" },  { name = "compile", run = "pnpm tsc --noEmit" },  { name = "bundle",  run = "pnpm vite build", cache = "dist/**" },] [jobs.test]depends = ["build"]steps = [  { name = "unit",   run = "pnpm vitest run" },  { name = "report", run = "pnpm report write" },]
A single file declares jobs, steps, and environments.

§ 03 — where to next

Pick the first chapter.