Tools

just: put project commands in a justfile, simpler than a Makefile

TL;DR

just stores project commands in a justfile with Make-like syntax but no .PHONY, plus parameters, dependencies, [confirm] for risky recipes and just --list as documentation. Use the same recipes locally and in CI.

Every project has a set of commands people run over and over: run tests, lint, build the Docker image, migrate the database, deploy to staging. Many teams put them in a Makefile and then trip over mandatory tabs, .PHONY, and the fact that Make was built for producing files, not running commands. Others scatter them in a README nobody updates. just is a command runner: store commands (called recipes) in a justfile with Make-like but simpler syntax, and run them with just recipe-name.

GitHub page of casey/just
GitHub page of casey/just (screenshot, November 2026)

GitHub: https://github.com/casey/just · about 37k stars · Rust · CC0-1.0

Installation

brew install just                        # macOS
cargo install just                       # with Rust
winget install --id Casey.Just --exact   # Windows
sudo apt install just                    # Ubuntu 24.04 and later

Your first justfile

Create a justfile at the project root:

# Load variables from .env
set dotenv-load

image := "myapp"
version := `git rev-parse --short HEAD`

# The first recipe is the default when you type `just`
default:
    @just --list

# Install dependencies
install:
    npm ci

# Run tests, forwarding any extra arguments
test *args:
    npm test -- {{args}}

# Build the image; depends on test
build: test
    docker build -t {{image}}:{{version}} .

# Deploy with a defaulted parameter and a confirmation prompt
[confirm("Really deploy?")]
deploy env="staging": build
    ./scripts/deploy.sh {{env}} {{image}}:{{version}}
just               # list recipes with their comments
just test --watch  # pass arguments
just deploy prod   # test → build → confirm → deploy prod

Why not Make?

CriterionMakejust
Original purposeBuild files based on modification timesRun commands
.PHONYRequiredNot needed
ArgumentsThrough variables, clumsyNamed parameters, defaults, variadic
Listing commandsWrite it yourselfjust --list built in, comments as descriptions
ErrorsWhen execution reaches themUnknown recipes or variables reported before running
Cross-platformAwkward on WindowsLinux, macOS, Windows

Features worth knowing

  • Recipes in other languages: start a recipe with a shebang (#!/usr/bin/env python3) and it runs as a Python script.
  • Change the shell: set shell := ["bash", "-uc"].
  • Run from subdirectories: just searches parent directories for a justfile, so just test works anywhere in the project.
  • Quiet lines: prefix a line with @ so the command isn't echoed before running.
  • Attributes: [confirm] asks before running, [private] hides from the list, [linux]/[macos]/[windows] for OS-specific recipes.

Caveats

  • just doesn't track whether files are up to date; each call runs again. For incremental builds, keep a real build tool.
  • Each recipe line runs in a new shell; shell variables and cd don't persist between lines. Use a shebang recipe when you need state.
  • Recipe indentation can be tabs or spaces, but must be consistent within a recipe.

How to apply it

  • Dev: Collect all of the project's common commands in a justfile; newcomers just type just to learn how the project runs.
  • Tech Lead: Have CI call the same recipes as developers (just test, just build) to end "CI behaves differently from my machine".
  • PM: A justfile is living documentation of the project's technical workflow, always correct because it's executed every day.

Sources & references

  1. casey/just — casey (GitHub)