runner-run 0.11.0

Universal project task runner
Documentation

runner

Crates.io NPM License: MIT

runner is for people who bounce between codebases and refuse to memorize each repo’s private little task-running religion.

Instead of guessing whether this one wants npm run, pnpm exec, bunx, cargo, uv run, deno task, turbo, make, just, etc. type:

run <TAB>
❯ run
run 0.10.0

  Package Managers    cargo
  Task Runners        just, bacon

  justfile        build-packages
  justfile        default
  justfile        gen-schema           just gen-schema && git diff --exit-code schemas/
  justfile        install
  justfile        ls
  justfile        run
  justfile        runner
  justfile        test-release         Build release bin and verify the facade shims spawn the native binary.
  config.toml     b                    build
  config.toml     bb                   build --bin run --bin runner
  config.toml     bbr                  build --bin run --bin runner --release
  config.toml     bin-run              run --bin run --quiet
  config.toml     bin-runner           run --bin runner --quiet
  config.toml     c                    check
  config.toml     cl                   clippy --all-targets --all-features
  config.toml     comp                 run --bin runner --quiet -- completions
  config.toml     d                    doc
  config.toml     i                    install --path .
  config.toml     l                    clippy --all-targets --all-features -- -D warnings -D clippy::all
  config.toml     lint                 clippy --all-targets --all-features -- -D warnings -D clippy::all
  config.toml     meta                 metadata --format-version 1
  config.toml     r                    run
  config.toml     rbin-run             run --bin run --quiet --release
  config.toml     rbin-runner          run --bin runner --quiet --release
  config.toml     rm                   remove
  config.toml     rr                   run --release
  config.toml     runner               run --bin runner
  config.toml     schema               run --quiet --example gen-schema --features schema-gen
  config.toml     t                    test
  bacon.toml      bins                 cargo build --bin runner --bin run --color=always
  bacon.toml      check                cargo check
  bacon.toml      check-all            cargo check --all-targets
  bacon.toml      clippy               cargo clippy
  bacon.toml      clippy-all           cargo clippy --all-targets
  bacon.toml      doc                  cargo doc --no-deps
  bacon.toml      doc-open             cargo doc --no-deps --open
  bacon.toml      ex                   cargo run --example
  bacon.toml      lint                 cargo clippy --all-targets --all-features --color=always -- -D warnings -D clippy::all
  bacon.toml      nextest              cargo nextest run --hide-progress-bar --failure-output final
  bacon.toml      pedantic             cargo clippy -- -W clippy::pedantic
  bacon.toml      run                  cargo run
  bacon.toml      run-long             cargo run
  bacon.toml      test                 cargo test
  bacon.toml      test-all             cargo test --all-features --all-targets --color=always

and run <TAB> (zsh):

❯ run <TAB>waiting...
-- justfile --
build-packages
default
gen-schema                     -- just gen-schema && git diff --exit-code schemas/
install
ls
run
justfile:run
runner
justfile:runner
test-release                   -- Build release bin and verify the facade shims spawn the native binary.
-- cargo --
b                              -- build
bb                             -- build --bin run --bin runner
bbr                            -- build --bin run --bin runner --release
bin-run                        -- run --bin run --quiet
bin-runner                     -- run --bin runner --quiet
c                              -- check
cl                             -- clippy --all-targets --all-features
comp                           -- run --bin runner --quiet -- completions
d                              -- doc
i                              -- install --path .
l                              -- clippy --all-targets --all-features -- -D warnings -D clippy::all
lint                           -- clippy --all-targets --all-features -- -D warnings -D clippy::all
cargo:lint                     -- clippy --all-targets --all-features -- -D warnings -D clippy::all
meta                           -- metadata --format-version 1
r                              -- run
rbin-run                       -- run --bin run --quiet --release
rbin-runner                    -- run --bin runner --quiet --release
rm                             -- remove
rr                             -- run --release
cargo:runner                   -- run --bin runner
schema                         -- run --quiet --example gen-schema --features schema-gen
t                              -- test
-- bacon.toml --
bins                           -- cargo build --bin runner --bin run --color=always
check                          -- cargo check
check-all                      -- cargo check --all-targets
clippy                         -- cargo clippy
clippy-all                     -- cargo clippy --all-targets
doc                            -- cargo doc --no-deps
doc-open                       -- cargo doc --no-deps --open
ex                             -- cargo run --example
bacon.toml:lint                -- cargo clippy --all-targets --all-features --color=always -- -D warnings -D clippy::all
nextest                        -- cargo nextest run --hide-progress-bar --failure-output final
pedantic                       -- cargo clippy -- -W clippy::pedantic
bacon.toml:run                 -- cargo run
run-long                       -- cargo run
test                           -- cargo test
test-all                       -- cargo test --all-features --all-targets --color=always
-- Options --
--dir                          -- Use this directory instead of the current one
--pm                           -- Override the detected package manager (e.g. pnpm, bun, yarn). Also reads RUNNER_PM when omitted.
--runner                       -- Override the detected task runner (e.g. just, turbo, make). Also reads RUNNER_RUNNER when omitted.
--fallback                     -- What to do when no detection signal matches: probe (default, PATH probe), npm (legacy silent fallback), error (refuse). Also reads RUNNER_FALLBACK when omitted.
--on-mismatch                  -- What to do when the manifest declaration disagrees with the lockfile: warn (default), error (exit 2), ignore (silent). Also reads RUNNER_ON_MISMATCH when omitted.
--explain                      -- Print a one-line trace describing how the package manager was resolved. Also enabled when RUNNER_EXPLAIN is set to a truthy value.
--no-warnings                  -- Suppress all non-fatal warnings on stderr. Also enabled when RUNNER_NO_WARNINGS is set to a truthy value.
--help                         -- Print help
--version                      -- Print version

runner detects the project, finds its tasks, and completes them through one command.

Use the same shape everywhere:

run <TAB>
runner install --frozen
run test
run build
run deploy

Let each repo decide what the tasks actually mean.

Install

npm install -g runner-run

Or:

cargo binstall runner-run
cargo install runner-run
cargo install --git=https://github.com/kjanat/runner/ runner-run
cargo install --path .
curl -fsSLO https://raw.githubusercontent.com/kjanat/runner/master/install.sh
bash install.sh
bash install.sh 0.10.0
bash install.sh v0.10.0

GitHub Actions

Use the action to install runner in CI:

- uses: kjanat/runner@master
- run: runner install --frozen
- run: run test
- run: run build

runner install here is not a task, but runs the needed toolchain command(s) for the project, such as npm ci, cargo fetch, uv sync, etc.

That is the point: the workflow stays boring even when the project underneath is npm, pnpm, bun, Cargo, Deno, uv, Make, just, or whatever automation that repo uses.

The action installs the runner-run npm package into the runner tool cache with npm install --global --ignore-scripts --prefix, verifies the installed runner shim by running runner --version, and adds the npm bin directory to PATH for later steps.

I/O name description
Input version npm version spec for runner-run; defaults to latest; accepts numeric v? forms
Output version Concrete version reported by the installed runner --version smoke test
Output bin-dir npm global bin directory containing runner / run; added to PATH for later steps

Exact X.Y.Z pins are checked against the executed CLI version; a mismatch fails the action.


Usage

runner                              # show detected project info
runner <task> [-- <args...>]        # run a task
runner run <target> [-- <args...>]  # run a task or command
run <target> [-- <args...>]         # alias for `runner run`

runner install [--frozen]           # install dependencies
runner clean [-y] [--include-framework]
runner list [--raw] [--json]        # list available tasks
runner info [--json]                # show detected project info
runner doctor [--json]              # show every resolver signal
runner why <task> [--json]          # explain how a task would dispatch
runner completions [<shell>] [-o <path>]

Completions

runner completions generates dynamic shell completion registrations.

For bash, zsh, and fish, runner can auto-detect $SHELL:

eval "$(runner completions)"
eval "$(runner completions bash)"
eval "$(runner completions zsh)"
eval "$(runner completions fish)"

PowerShell

runner completions powershell | Out-String | Invoke-Expression

The generated registration includes runner and, when the sibling run binary exists next to it, run too.

So after setup, this is the workflow:

run <TAB>

No per-project command archaeology. No guessing whether this one wants npm, Cargo, Make, just, Deno, uv, or some handcrafted nonsense from 2021.

Task Resolution

runner run <target> first looks for a matching task.

If no task exists, it falls back to executing <target> through the detected toolchain where appropriate, such as:

npm exec / npx, yarn run / yarn exec, pnpm exec, bun x / bunx,
deno x, uvx, go run

For package managers without a matching exec primitive, runner falls back to executing <target> directly from PATH.

The run binary is equivalent to runner run, so:

run clean
run install

runs a task or command named clean or install, even when those names also exist as built-in runner subcommands.

Supported Ecosystems

runner detects and works with:

npm, yarn, pnpm, bun, cargo, deno, uv, poetry, pipenv, go, bundler, composer

It can list and run tasks from:

package.json / package.json5 / package.yaml
turbo.json / turbo.jsonc
deno.json / deno.jsonc
Makefile
justfile
Taskfile
bacon.toml
mise.toml / .mise.toml
Cargo aliases from .cargo/config.toml

It also understands monorepo/workspace context from:

turbo, nx, pnpm, npm/yarn workspaces, Cargo workspaces

nx is currently detection-only. runner uses it for project context, but does not extract Nx tasks as direct task entries yet.

When multiple sources define the same task, runner chooses deterministically: turbo tasks first, then package manifest scripts, then other matching sources.


Features

  • run <TAB> task completion across projects
  • One command shape across many ecosystems
  • Simple CI with runner install --frozen plus run <task> steps
  • First-class GitHub Actions install step
  • Automatic toolchain detection
  • Task aggregation from common config files
  • Task-first execution with command fallback
  • Monorepo/workspace awareness
  • Safe clean defaults
  • Node version mismatch warnings

Development

./bin/runner <args>
./bin/run <args>

With direnv:

runner <args>

Links

License

MIT © 2026 Kaj Kowalski