This document covers the internal design, architecture, and behavior of cmd-runner.
cmd-runner is built around a few key abstractions:
CommandRunner: The main struct that manages the execution context, including the current directory and the project root. It orchestrates command discovery and execution.CommandSourceInterface: An interface that each build system (like npm, cargo, or make) implements. It has methods to list available commands and find a specific command. This makes the tool extensible.
cmd-runner uses a multi-step process to find the right command to execute:
- First searches in the current directory for a matching command source (e.g., a
package.jsonorMakefile). - Then searches in the project root (determined by the presence of a
.jjor.gitdirectory). - Tries command aliases (e.g.,
fmtforformat,devforrun).
The tool searches for commands from different build systems in the following order of priority:
- mise -
.mise.toml(polyglot runtime manager) - just -
justfileorJustfile(command runner) - make -
Makefileormakefile(classic build tool) - Node.js -
package.jsonwith bun/pnpm/yarn/npm - Rust -
Cargo.toml(cargo) - Go -
go.mod(go modules) - Python -
pyproject.tomlwith uv - Java/Kotlin -
build.gradle[.kts](gradle) orpom.xml(maven)
| Command | Aliases | Short | Description |
|---|---|---|---|
format |
fmt |
f |
Code formatting |
test |
tests |
t |
Run tests |
typecheck |
type-check, types |
tc |
Run type checker |
run |
dev, serve, start |
r |
Run development server or application |
serve |
dev, run, start |
s |
Run server (alias for run) |
build |
- | b |
Build the project |
lint |
- | l |
Run linters |
check |
- | - | Run lint, typecheck, and test together |
fix |
- | - | Auto-fix issues |
clean |
- | - | Clean build artifacts |
setup |
- | - | Install dependencies for local development |
install |
- | - | Install binary/package globally |
Note: If a project has an actual command named f, t, etc., it will take precedence over the short alias expansion.
check: If no nativecheckcommand exists,cmd-runnerautomatically runslint,typecheck, andtestin sequence.fix: If no nativefixcommand exists, it automatically runsformatandlint --fix.typecheck: It will error if the project doesn't support type checking (e.g., no TypeScript, Python with pyright/mypy, Rust, or Go).
- Package Managers: bun, pnpm, yarn, npm, deno
- Type Checking: TypeScript (
tsc) - Common Tools: biome, eslint, prettier
- Package Manager: uv (with pyproject.toml)
- Type Checking: pyright, mypy
- Common Tools: ruff, pytest
- Build System: cargo
- Type Checking: Built-in (
cargo check) - Common Tools: clippy, rustfmt
- Build System: go modules
- Type Checking: Built-in (
go build) - Common Tools: go vet, gofmt
- Build Systems: gradle, maven
- Type Checking: Built-in compilation