Stop Fighting Make: just Is the Command Runner You Actually Want
You know that feeling when you just want to run a quick test or deploy script, but instead you're staring at a Makefile trying to remember whether you need a .PHONY declaration or why tabs suddenly broke everything? Make is a build tool, not a command runner, and using it for the latter means wrestling with decades of accumulated complexity. That's where just comes in—a command runner that saves your project-specific commands in a justfile with syntax inspired by make, but without all the baggage.
What It Does
just is a straightforward utility for saving and running project-specific commands. You define recipes—think of them as named shell commands—in a file called justfile. The syntax looks familiar if you've used make, but it's designed specifically for running commands, not building software. You invoke them with just RECIPE_NAME, and just executes the associated shell commands.
Under the hood, just is written in Rust and distributed as a single binary. It supports Linux, macOS, Windows, and other Unix-like systems. On Windows, it works with the sh shell provided by Git for Windows, GitHub Desktop, or Cygwin—though you can also configure it to use a different shell if you prefer. The project is actively maintained, with pre-built binaries available for download, support through popular package managers, and installation via cargo install just if you're already in the Rust ecosystem.
Why It's Cool
The real appeal of just isn't just that it exists—it's that it solves the specific pain points that make developers reach for make in the first place and then regret it. Here's what stands out:
-
No more
.PHONYnonsense. Make assumes every recipe creates a file, so you need.PHONYdeclarations to tell it otherwise.justis a command runner, not a build system, so it skips that entire class of problems. Your recipes just run. -
Errors you can actually understand. When something goes wrong,
justgives you specific, informative error messages. Syntax errors are reported with their source context, so you're not hunting through a cryptic log to find the problem. -
Real arguments and flags. Recipes in
justcan accept command-line arguments, including flags and options. That's a huge quality-of-life improvement over make's clunky variable passing. -
A proper expression language.
justincludes a rich expression language and built-in functions, so you can write more sophisticated recipes without resorting to shell script gymnastics. -
Static error checking. Wherever possible,
justresolves errors before anything runs. Unknown recipes and circular dependencies are caught upfront, not halfway through a build. -
It works from anywhere. You can invoke
justfrom any subdirectory, not just the one containing thejustfile. That alone removes a constant source of friction. -
Environment variables from
.envfiles.justloads.envfiles automatically, making it easy to populate environment variables without manualexportstatements. -
Recipes in any language. Need to write a recipe in Python or Node.js?
justsupports shebang recipes, so you're not locked into shell. -
Organized justfiles. As your project grows, you can split
justfiles into multiple files using modules and imports. It scales with your project instead of becoming a monolithic mess. -
Shell completions built in. Command-line completion scripts are available for most popular shells, so you don't have to remember every recipe name.
-
No dependencies required. On most systems,
justruns with no additional dependencies beyond a reasonablesh. It's a single tool that just works.
How to Try It
Getting started with just is painless. First, install it using your preferred method. If you use a package manager, check if it's available—otherwise, grab a pre-built binary from the releases page or install from source:
$ cargo install just
Once installed, create a justfile in your project root. Here's a minimal example to get you started:
test-all:
cc *.c -o main
./test --all
echo "Yay, all your tests passed!"
Then run it:
$ just test-all
cc *.c -o main
./test --all
Yay, all your tests passed!
You can list available recipes from the command line, pass arguments to recipes, and start organizing your commands into modules as your justfile grows. The full documentation is available as a book online, and the GitHub repository has everything you need to dive deeper.
Final Thoughts
just isn't trying to replace make for actual build automation—it's for the other 80% of what you probably use make for anyway: running project-specific commands. If you've ever added a .PHONY target just to run a test script or cursed at make's error messages, just is worth a try. It's simple enough to adopt in an afternoon, and the improvements over make are immediately noticeable. For developers who want to spend less time fighting their tools and more time shipping code, just hits a sweet spot between simplicity and power.
Follow @githubprojects for more developer tools and open source projects.