Rust

Just Task Runner

Using Just as a command runner for Rust projects — recipes, variables, cross-platform support, and real-world patterns.

Why Just?

Just is a command runner inspired by make, but designed for running project-specific commands rather than building software. It's written in Rust, installs as a single binary, and avoids the quirks of Makefiles (tabs vs spaces, implicit rules, .PHONY).

Terminal
# Install
cargo install just
# or
brew install just

Justfile Basics

Create a justfile (no extension) in your project root:

justfile
# List available recipes
default:
    @just --list

# Run all tests
test:
    cargo test

# Run tests with output
test-verbose:
    cargo test -- --nocapture

# Check formatting, lints, and tests
check: fmt clippy test

# Format code
fmt:
    cargo fmt --check

# Run clippy
clippy:
    cargo clippy -- -D warnings

Run recipes with just <name>:

Terminal
just test
just check

Variables and Arguments

Recipes can accept arguments and use variables:

justfile
# Default version from Cargo.toml
version := `grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/'`

# Run a specific test
test-one name:
    cargo test {{name}} -- --nocapture

# Tag and release
release:
    @echo "Releasing v{{version}}"
    git tag -a "v{{version}}" -m "v{{version}}"
    git push origin "v{{version}}"
    gh release create "v{{version}}" --title "v{{version}}" --generate-notes --target main

Conditional Logic and OS Detection

Just supports if statements and detects the operating system:

justfile
# Platform-specific open command
open-docs:
    #!/usr/bin/env bash
    if [[ "{{os()}}" == "macos" ]]; then
        open target/doc/my_crate/index.html
    else
        xdg-open target/doc/my_crate/index.html
    fi

# Only run if file exists
bench:
    #!/usr/bin/env bash
    if [ -d "benches" ]; then
        cargo bench
    else
        echo "No benchmarks found"
    fi

Real-World Patterns

Rust Crate Development

A complete justfile for a published crate:

justfile
default:
    @just --list

# Run all tests
test:
    cargo test

# Run clippy with warnings as errors
clippy:
    cargo clippy -- -D warnings

# Build documentation
docs:
    cargo doc --no-deps --open

# Pre-publish validation
pre-publish:
    cargo fmt --check
    cargo clippy -- -D warnings
    cargo test
    cargo doc --no-deps
    cargo publish --dry-run

# Full CI check
ci: fmt clippy test docs
    @echo "All checks passed ✅"

fmt:
    cargo fmt --check

Workspace with Multiple Crates

For monorepos or multi-crate workspaces:

justfile
# Run tests across all repos
test-all:
    #!/usr/bin/env bash
    for dir in rfconversions touchstone gainlineup linkbudget; do
        echo "Testing $dir..."
        (cd ~/Development/$dir && cargo test) || exit 1
    done

# Check versions across crates
crate-versions:
    ./scripts/crate-versions.sh

# Show repo status dashboard
status:
    ./scripts/repo-status.sh

# Pull all repos
pull-all:
    #!/usr/bin/env bash
    for dir in ~/Development/*/; do
        if [ -d "$dir/.git" ]; then
            echo "Pulling $(basename $dir)..."
            git -C "$dir" pull --rebase 2>/dev/null || true
        fi
    done

Development Server

For web projects with hot reload:

justfile
# Start dev server
dev:
    cargo watch -x run

# Start with specific port
dev-port port="3000":
    PORT={{port}} cargo watch -x run

# Run database migrations then start
serve: migrate dev

migrate:
    sqlx migrate run

Environment Variables

Just can load .env files and set environment variables:

justfile
set dotenv-load

# Uses DATABASE_URL from .env
migrate:
    sqlx migrate run

# Override for specific recipe
test-db:
    DATABASE_URL="sqlite::memory:" cargo test

Tips

Shell Recipes

Multi-line recipes with #!/usr/bin/env bash get executed as a single script (not line-by-line like make):

justfile
complex-task:
    #!/usr/bin/env bash
    set -euo pipefail
    files=$(find . -name "*.rs" | wc -l)
    echo "Found $files Rust files"
    if [ "$files" -gt 100 ]; then
        echo "That's a lot of Rust!"
    fi

Quiet and Confirmation

justfile
# @ suppresses the command echo
list:
    @ls -la

# [confirm] asks before running
[confirm("Delete all build artifacts?")]
clean:
    cargo clean

Dependencies Between Recipes

justfile
build: fmt clippy
    cargo build --release

fmt:
    cargo fmt

clippy:
    cargo clippy -- -D warnings

Running just build automatically runs fmt and clippy first.

Just vs Make vs Scripts

FeatureJustMakeShell Scripts
Tab sensitivityNoYesNo
ArgumentsBuilt-inAwkward$1, $2
Cross-platformYesVariesVaries
.env loadingBuilt-inManualManual
Listing recipesjust --listNot built-inManual
DependenciesSimpleComplexManual

Further Reading