Last updated on 5th August 2026

just: A Command Runner for Your Project's Tasks

Every project ends up with a handful of commands everyone needs to remember: how to install dependencies, run the build, run the tests, start the dev server, cut a release. Those commands usually live in a README, a pile of shell scripts, or a package.json scripts block that only works for Node projects. just gives them a proper home.

just is a command runner — a single tool for saving and running project-specific commands from a file called a justfile. If you've reached for a Makefile to do this and fought with tabs, phony targets, and shell quirks, just is the purpose-built alternative: the same "run a named recipe" convenience, without the baggage.

What just is (and isn't)

just is not a build system. It won't track file timestamps or decide what needs recompiling the way make does. It does one thing well: it stores commands as named recipes and runs them. That narrow focus is the point — it's a friendlier, more predictable replacement for the way most teams (ab)use Makefiles as task runners.

It's a single Rust binary, works the same on macOS, Linux, and Windows, and is language-agnostic: the recipes inside can run anything.

Installing just

# macOS / Linux
brew install just

# Windows
winget install --id Casey.Just

# Any platform with Rust
cargo install just

Your first justfile

Create a file named justfile in your project root:

# install dependencies
install:
    npm ci

# build the app (runs install first)
build: install
    npm run build

# run the test suite (runs build first)
test: build
    npm test

Now run recipes by name:

just build        # runs install, then build
just test         # runs install, build, then test
just              # runs the first recipe (or the default)
just --list       # show every available recipe

The test: build syntax declares a dependency: asking for test runs build first, which runs install first. You describe what depends on what once, and just resolves the order.

Recipes that take arguments

Recipes can accept parameters, which makes them far more flexible than a static script:

# deploy to a named environment
deploy target:
    ./scripts/deploy.sh {{target}}
just deploy staging
just deploy production

You can also define variables and reuse them:

node_env := "production"

build:
    NODE_ENV={{node_env}} npm run build

Loading environment variables

just can load a .env file automatically so your recipes have the variables they need, without you exporting them by hand:

set dotenv-load

start:
    node server.js    # sees everything from .env

Keep real secrets out of a plaintext .env, though. For anything sensitive, encrypt your .env files with dotenvx and decrypt them at runtime rather than committing raw values.

Recipes in other languages

A recipe isn't limited to shell. With a shebang, it runs in whatever interpreter you name — handy for a quick script that would be awkward in bash:

count-files:
    #!/usr/bin/env python3
    import os
    print(len(os.listdir(".")))

Using just with DeployHQ

Here's where just pays off for deployment specifically: the recipes you run locally are the exact commands your build pipeline should run. You've already written just build to mean npm ci && npm run build — so there's a single, version-controlled definition of how your project is built, and no drift between "what I run on my laptop" and "what the server runs."

There are two clean ways to wire that into DeployHQ:

  1. Mirror the commands. Copy the commands from your recipe into your project's build pipeline steps. The justfile stays the human-friendly local entry point; the pipeline runs the same underlying commands.
  2. Install just as a build step, then call the recipe directly, so both sides literally run the same recipe:
   cargo install just
   just build

Either way, once your build commands live in a recipe, enable automatic deployments so every push runs that same build and ships the result — the command you tested locally is the command that reaches production.

just vs a full task runner

If all you need is named commands with dependencies, just is hard to beat for simplicity. If you also want to manage the runtime versions those commands run against, or load per-project environment variables, a broader tool may fit better — you can define tasks alongside runtimes and env with mise in one file. Many teams happily use both: mise for versions and environment, just for the day-to-day command menu.

Ready to run the same build on your server that you run locally? Create a free DeployHQ account and connect your repository in minutes.