Skip to content

kjanat/runner

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

406 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

runner

Fallback image

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 ran in this very project
❯ 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
Other install methods
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.

Install mechanics and outputs

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)"
...or get explicit with it
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
Support notes

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

About

Universal project task runner

Resources

License

Stars

Watchers

Forks

Contributors