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).
# Install
cargo install just
# or
brew install just
Create a justfile (no extension) in your project root:
# 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>:
just test
just check
Recipes can accept arguments and use variables:
# 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
Just supports if statements and detects the operating system:
# 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
A complete justfile for a published crate:
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
For monorepos or multi-crate workspaces:
# 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
For web projects with hot reload:
# 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
Just can load .env files and set environment variables:
set dotenv-load
# Uses DATABASE_URL from .env
migrate:
sqlx migrate run
# Override for specific recipe
test-db:
DATABASE_URL="sqlite::memory:" cargo test
Multi-line recipes with #!/usr/bin/env bash get executed as a single script (not line-by-line like make):
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
# @ suppresses the command echo
list:
@ls -la
# [confirm] asks before running
[confirm("Delete all build artifacts?")]
clean:
cargo clean
build: fmt clippy
cargo build --release
fmt:
cargo fmt
clippy:
cargo clippy -- -D warnings
Running just build automatically runs fmt and clippy first.
| Feature | Just | Make | Shell Scripts |
|---|---|---|---|
| Tab sensitivity | No | Yes | No |
| Arguments | Built-in | Awkward | $1, $2 |
| Cross-platform | Yes | Varies | Varies |
.env loading | Built-in | Manual | Manual |
| Listing recipes | just --list | Not built-in | Manual |
| Dependencies | Simple | Complex | Manual |