Here is the complete product specification:


Product Specification: just

Inferred from source review, documentation, tests, and CI configuration of casey/just. Statements reflect observed behavior and public documentation, not author claims.


1. Problem Statement

Developers on any project accumulate a collection of commands they run repeatedly: building, testing, linting, deploying, seeding databases, resetting environments. These commands are long, easy to mistype, and differ between team members because they live in personal notes, shell history, or READMEs that quickly go stale.

make is the traditional solution, but it was designed as a build system, not a command runner. Using it for general task automation forces developers to work around its file-timestamp model, .PHONY declarations, tab-only indentation, and unintuitive variable scoping.

just solves this by providing a dedicated command runner: a single, portable tool that reads a justfile in the project directory, validates the task graph before running anything, and executes named recipes reliably from any subdirectory. It makes project-level commands first-class, reproducible, and discoverable.


2. Actors and Their Goals

Developer (primary user)

Team Lead / Project Maintainer

CI/CD System (automation actor)

Integrator (shell/editor tooling)


3. Operator Value

Without just With just
Commands live in personal notes or READMEs and drift Commands are versioned in the project repo alongside code
Developers must remember long, fragile shell invocations Short recipe names invoke complex commands reliably
Errors discovered mid-execution after partial side effects Recipe graph validated before any command runs
Onboarding requires reading prose docs to find commands just --list reveals all available commands instantly
make workarounds required for non-build tasks A purpose-built runner with no build-system impedance
Platform differences cause silent breakage Cross-platform recipe syntax with explicit OS conditions

4. Core Capabilities

4.1 Recipe Definition and Execution

The system allows a developer to define named recipes in a justfile and invoke them by name from the command line. A recipe is a named, ordered sequence of shell commands. Recipes may depend on other recipes. The system executes the full dependency graph in declaration order, deduplicating recipes that appear multiple times.

4.2 Parameterized Recipes

Recipes accept named parameters with optional defaults. Parameters may be required or variadic (accepting one or more, or zero or more values). Arguments are passed positionally on the command line after the recipe name. The system makes parameters available as interpolations within recipe commands and, optionally, as environment variables.

4.3 Variables and Expressions

The justfile supports named variables whose values are string literals, shell command outputs (evaluated at load time via backtick expressions), or computed expressions using built-in functions. Variables may be exported to the shell environment of all recipe commands. Variable values can be overridden at invocation time via CLI flags or environment variables.

4.4 Pre-execution Validation

Before running any commands, the system validates the full recipe graph: it detects undefined recipes, circular dependencies, missing required parameters, and unknown identifiers. If validation fails, no commands run. This prevents partial execution side effects from misconfigured justfiles.

4.5 Recipe Discovery and Listing

The system can list all available (non-private) recipes with their parameters and doc comments. Recipes can be grouped and filtered. The listing can be rendered as human-readable text or as structured JSON for tooling consumption. Private recipes (prefixed with _ or marked with an attribute) are hidden from listings by default.

4.6 Multi-Recipe Invocation

A developer can invoke multiple recipes in a single just command. Each is executed in the order specified. Recipes are deduplicated across the full invocation: the same recipe with the same arguments runs only once.

4.7 Cross-Platform Execution

The system operates on Linux, macOS, Windows, and BSD platforms. Recipes can be conditioned on the operating system via attributes, so a single justfile can encode platform-specific variants of a command. The path-join operator always uses forward slashes regardless of host platform.

4.8 Modular Justfiles

A justfile can include other justfile modules by name. Each module has its own isolated namespace for variables and recipes. Recipes from modules are invoked using a module::recipe path syntax. Modules may be optional (no error if the file is absent).

4.9 Shell and Environment Configuration

The system supports configuring the shell used to execute recipes (interpreter and flags). It can automatically load a .env file and inject its contents as environment variables before recipe execution. The search path for the .env file is configurable.

4.10 Interactive and Scripted Modes

The system provides an interactive recipe chooser (backed by a configurable fuzzy-finder) for exploratory use. Recipes can require confirmation before executing, with a customizable prompt. Dry-run mode prints all commands that would execute without running them.

4.11 Formatting and Editing

The system can reformat a justfile to canonical style in place, or verify that an existing file is already canonically formatted (for use in CI). It can open the justfile in the user's configured editor. It can initialize a new justfile with a starter template.

4.12 Shell Completion

The system can emit completion scripts for common shells, enabling tab-completion of recipe names and flags in the developer's terminal.

4.13 Built-in Function Library

The system provides a library of pure functions available in justfile expressions, covering: string manipulation, path decomposition, environment inspection, hashing, UUID generation, date/time formatting, OS detection, filesystem queries, and terminal color/style sequences.

When invoked from a subdirectory, the system ascends the directory tree to find the nearest justfile, allowing recipes to be run from anywhere within a project. The search can be bounded to prevent ascending above a specified ceiling directory.

4.15 Global Justfile

A developer can maintain a personal justfile at a fixed location and invoke it from anywhere using a flag, providing a personal command library independent of any project.


5. Observable Behaviors

Recipe Execution

Argument Handling

Output Streams

Exit Codes

Dependency Deduplication

Dry Run

Listing

Justfile Location

Default Recipe

Confirmation Gate

Dotenv Loading

Module Invocation

Formatting Check


6. Edge Cases and Failure Behavior


7. Non-Functional Constraints


8. Non-Goals


9. Suspected Implementation Leakage

The following observations describe internal mechanisms rather than product-level promises. They belong in a technical or interface spec, not a product spec: