
Cli Just
- 10 installs
- 5 repo stars
- Updated August 4, 2026
- paulrberg/dot-agents
Helps with ai & agent building tasks.
About
cli-just is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- cli-just
- AI & Agent Building
- AI-coding skill
Cli Just by the numbers
- 10 all-time installs (skills.sh)
- +1 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #11,959 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/paulrberg/dot-agents --skill cli-justAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 10 |
|---|---|
| repo stars | ★ 5 |
| Last updated | August 4, 2026 |
| Repository | paulrberg/dot-agents ↗ |
What it does
Helps with ai & agent building tasks.
Files
Just Command Runner
Overview
Expert guidance for Just, a command runner with syntax inspired by make. Use this skill for creating justfiles, writing recipes, configuring settings, and implementing task automation workflows.
Key capabilities:
- Create and organize justfiles with proper structure
- Write recipes with attributes, dependencies, and parameters
- Configure settings for shell, modules, and imports
- Use built-in constants for terminal formatting
- Implement check/write patterns for code quality tools
Quick Reference
Essential Settings
set allow-duplicate-recipes # Allow recipes to override imported ones
set allow-duplicate-variables # Allow variables to override imported ones
set shell := ["bash", "-euo", "pipefail", "-c"] # Strict bash with error handling
set unstable # Enable unstable features (modules, script attribute)
set dotenv-load # Auto-load .env file
set positional-arguments # Pass recipe args as $1, $2, etc.Common Attributes
| Attribute | Purpose |
|---|---|
[arg("p", long, ...)] | Configure parameter as --flag option (v1.46) |
[arg("p", pattern="…")] | Constrain parameter to match regex pattern |
[group("name")] | Group recipes in just --list output |
[no-cd] | Don't change to justfile directory |
[private] | Hide from just --list (same as _ prefix) |
[script] | Execute recipe as single script block |
[script("interpreter")] | Use specific interpreter (bash, python, etc.) |
[confirm("prompt")] | Require user confirmation before running |
[doc("text")] | Override recipe documentation |
[positional-arguments] | Enable positional args for this recipe only |
Recipe Argument Flags (v1.46.0+)
The [arg()] attribute configures parameters as CLI-style options:
# Long option (--target)
[arg("target", long)]
build target:
cargo build --target {{ target }}
# Short option (-v)
[arg("verbose", short="v")]
run verbose="false":
echo "Verbose: {{ verbose }}"
# Combined long + short
[arg("output", long, short="o")]
compile output:
gcc main.c -o {{ output }}
# Flag without value (presence sets to "true")
[arg("release", long, value="true")]
build release="false":
cargo build {{ if release == "true" { "--release" } else { "" } }}
# Help string (shown in `just --usage`)
[arg("target", long, help="Build target architecture")]
build target:
cargo build --target {{ target }}Usage examples:
just build --target x86_64
just build --target=x86_64
just compile -o main
just build --release
just --usage build # Show recipe argument helpMultiple attributes can be combined:
[no-cd, private]
[group("checks")]
recipe:
echo "hello"Built-in Constants
Terminal formatting constants are globally available (no definition needed):
| Constant | Description |
|---|---|
CYAN, GREEN, RED, YELLOW, BLUE, MAGENTA | Text colors |
BOLD, ITALIC, UNDERLINE, STRIKETHROUGH | Text styles |
NORMAL | Reset formatting |
BG_* | Background colors (BG_RED, BG_GREEN, etc.) |
HEX, HEXLOWER | Hexadecimal digits |
Usage:
@status:
echo -e '{{ GREEN }}Success!{{ NORMAL }}'
echo -e '{{ BOLD + CYAN }}Building...{{ NORMAL }}'Key Functions
# Require executable exists (fails recipe if not found)
jq := require("jq")
# Get environment variable with default
log_level := env("LOG_LEVEL", "info")
# Get justfile directory path
root := justfile_dir()Recipe Patterns
Status Reporter Pattern
Display formatted status during multi-step workflows:
@_run-with-status recipe *args:
echo ""
echo -e '{{ CYAN }}→ Running {{ recipe }}...{{ NORMAL }}'
just {{ recipe }} {{ args }}
echo -e '{{ GREEN }}✓ {{ recipe }} completed{{ NORMAL }}'
alias rws := _run-with-statusCheck/Write Pattern
Pair check (verify) and write (fix) recipes for code quality tools:
[group("checks")]
@biome-check +globs=".":
na biome check {{ globs }}
alias bc := biome-check
[group("checks")]
@biome-write +globs=".":
na biome check --write {{ globs }}
alias bw := biome-writeFull Check/Write Pattern
Aggregate all checks with status reporting:
[group("checks")]
@full-check:
just _run-with-status biome-check
just _run-with-status prettier-check
just _run-with-status tsc-check
echo ""
echo -e '{{ GREEN }}All code checks passed!{{ NORMAL }}'
alias fc := full-check
[group("checks")]
@full-write:
just _run-with-status biome-write
just _run-with-status prettier-write
echo ""
echo -e '{{ GREEN }}All code fixes applied!{{ NORMAL }}'
alias fw := full-writeStandard Alias Conventions
| Recipe | Alias | Recipe | Alias |
|---|---|---|---|
| full-check | fc | full-write | fw |
| biome-check | bc | biome-write | bw |
| prettier-check | pc | prettier-write | pw |
| mdformat-check | mc | mdformat-write | mw |
| tsc-check | tc | ruff-check | rc |
| test | t | build | b |
Inline Scripts
Just supports inline scripts in any language via two methods:
Script Attribute (Recommended)
Use [script("interpreter")] for cross-platform compatibility:
[script("node")]
fetch-data:
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
[script("python3")]
analyze:
import json
with open('package.json') as f:
pkg = json.load(f)
print(f"Package: {pkg['name']}@{pkg['version']}")
[script("bash")]
deploy:
set -e
npm run build
aws s3 sync dist/ s3://bucket/Shebang Method
Use #!/usr/bin/env interpreter at the recipe start:
node-script:
#!/usr/bin/env node
console.log(`Node ${process.version}`);
console.log(JSON.stringify(process.env, null, 2));
python-script:
#!/usr/bin/env python3
import sys
print(f"Python {sys.version}")
bash-script:
#!/usr/bin/env bash
set -euo pipefail
echo "Running on $(uname -s)"When to use which:
[script()]- Better cross-platform support, cleaner syntax- Shebang - Traditional Unix approach, works without
set unstable
Modules & Imports
Import Pattern
Include recipes from another file:
import "./just/settings.just"
import "./just/base.just"
import? "./local.just" # Optional (no error if missing)Module Pattern
Load submodule (requires set unstable):
mod foo # Loads foo.just or foo/justfile
mod bar "path/to/bar" # Custom path
mod? optional # Optional module
# Call module recipes
just foo::buildDevkit Import Pattern
For projects using @sablier/devkit:
import "./node_modules/@sablier/devkit/just/base.just"
import "./node_modules/@sablier/devkit/just/npm.just"Section Organization
Standard section header format:
# ---------------------------------------------------------------------------- #
# DEPENDENCIES #
# ---------------------------------------------------------------------------- #Common sections (in order):
1. DEPENDENCIES - Required tools with URLs 2. CONSTANTS - Glob patterns, environment vars 3. RECIPES / COMMANDS - Main entry points 4. CHECKS - Code quality recipes 5. UTILITIES / INTERNAL HELPERS - Private helpers
Default Recipe
Always define a default recipe:
# Show available commands
default:
@just --listDependencies Declaration
Document required tools at the top:
# ---------------------------------------------------------------------------- #
# DEPENDENCIES #
# ---------------------------------------------------------------------------- #
# Bun: https://bun.sh
bun := require("bun")
# Ni: https://github.com/antfu-collective/ni
na := require("na")
ni := require("ni")
nlx := require("nlx")
# Usage: invoke directly in recipes (not with interpolation)
build:
bun next buildNote: require() validates the tool exists at recipe evaluation time. Use the variable name directly (e.g., bun), not with interpolation ({{ bun }}).
Context7 Fallback
For Just features not covered in this skill (new attributes, advanced functions, edge cases), fetch the latest documentation:
Use context7 MCP with library ID `/websites/just_systems-man` to get up-to-date Just documentation.Example topics to search:
modules import mod- Module system detailssettings- All available settingsattributes- Recipe attributesfunctions- Built-in functionsscript recipes- Script block syntax
Additional Resources
Reference Files
For detailed patterns and comprehensive coverage, consult:
- [`references/settings.md`](references/settings.md) - Settings configuration and module system
- [`references/recipes.md`](references/recipes.md) - Recipe attributes, parameters, dependencies, and prefixes
- [`references/syntax.md`](references/syntax.md) - Constants, functions, variables, and CLI options
- [`references/patterns.md`](references/patterns.md) - Established conventions, section organization, helper patterns
Example Templates
Working justfile templates in examples/:
- [`devkit.just`](examples/devkit.just) - Minimal template importing @sablier/devkit
- [`standalone.just`](examples/standalone.just) - Full standalone template with all patterns
External Documentation
- Official Manual: https://just.systems/man/en/
- GitHub Repository: https://github.com/casey/just
- Context7 Library ID:
/websites/just_systems-man
Tips
1. Use @ prefix to suppress command echo: @echo "quiet" 2. Use + for variadic parameters: test +args 3. Use * for optional variadic: build *flags 4. Quote glob patterns in variables: GLOBS := "\"**/*.json\"" 5. Use [no-cd] in monorepos to stay in current directory 6. Private recipes start with _ or use [private] 7. Always define aliases after recipe names for discoverability
# See https://github.com/sablier-labs/devkit/blob/main/just/base.just
import "./node_modules/@sablier/devkit/just/base.just"
import "./node_modules/@sablier/devkit/just/npm.just"
# ---------------------------------------------------------------------------- #
# DEPENDENCIES #
# ---------------------------------------------------------------------------- #
# https://github.com/jqlang/jq
jq := require("jq")
# ---------------------------------------------------------------------------- #
# RECIPES #
# ---------------------------------------------------------------------------- #
# Default recipe
default:
@just --list
# Build the project
@build:
just clean
just tsc-build
alias b := build
# Clean the dist directory
@clean:
bunx del-cli dist
echo "✅ Cleaned build files"
# Run tests
test *args:
bun vitest run --hideSkippedTests {{args}}
alias t := test
# Run tests with UI
test-ui *args:
bun vitest --hideSkippedTests --ui {{args}}
alias tui := test-ui
set allow-duplicate-recipes
set allow-duplicate-variables
set shell := ["bash", "-euo", "pipefail", "-c"]
set unstable
# ---------------------------------------------------------------------------- #
# DEPENDENCIES #
# ---------------------------------------------------------------------------- #
# Bun: https://bun.sh
bun := require("bun")
# Ni: https://github.com/antfu-collective/ni
na := require("na")
ni := require("ni")
nlx := require("nlx")
# ---------------------------------------------------------------------------- #
# CONSTANTS #
# ---------------------------------------------------------------------------- #
GLOBS_PRETTIER := "\"**/*.{json,jsonc,yaml,yml}\""
# ---------------------------------------------------------------------------- #
# COMMANDS #
# ---------------------------------------------------------------------------- #
# Show available commands
default:
@just --list
# Install dependencies
[no-cd]
install *args:
ni {{ args }}
alias i := install
# Build the project
@build:
just clean
just tsc-build
alias b := build
# Clean build artifacts
@clean:
bunx del-cli dist
echo "✅ Cleaned build files"
# ---------------------------------------------------------------------------- #
# CHECKS #
# ---------------------------------------------------------------------------- #
# Run all code checks
[group("checks")]
[no-cd]
@full-check:
just _run-with-status biome-check
just _run-with-status prettier-check
just _run-with-status tsc-check
echo ""
echo -e '{{ GREEN }}All code checks passed!{{ NORMAL }}'
alias fc := full-check
# Run all code fixes
[group("checks")]
[no-cd]
@full-write:
just _run-with-status biome-write
just _run-with-status prettier-write
echo ""
echo -e '{{ GREEN }}All code fixes applied!{{ NORMAL }}'
alias fw := full-write
# Check code with Biome
[group("checks")]
[no-cd]
@biome-check +globs=".":
na biome check {{ globs }}
alias bc := biome-check
# Lint code with Biome
[group("checks")]
[no-cd]
@biome-lint +globs=".":
na biome lint {{ globs }}
alias bl := biome-lint
# Fix code with Biome
[group("checks")]
[no-cd]
@biome-write +globs=".":
na biome check --write {{ globs }}
na biome lint --unsafe --write --only correctness/noUnusedImports {{ globs }}
alias bw := biome-write
# Check Prettier formatting
[group("checks")]
[no-cd]
@prettier-check +globs=GLOBS_PRETTIER:
na prettier --check --cache --no-error-on-unmatched-pattern {{ globs }}
alias pc := prettier-check
# Format using Prettier
[group("checks")]
[no-cd]
@prettier-write +globs=GLOBS_PRETTIER:
na prettier --write --cache --no-error-on-unmatched-pattern {{ globs }}
alias pw := prettier-write
# Type check with TypeScript
[group("checks")]
[no-cd]
@type-check compiler="tsc" project="tsconfig.json":
na {{ compiler }} --noEmit --project {{ project }}
alias tc := type-check
# ---------------------------------------------------------------------------- #
# TESTS #
# ---------------------------------------------------------------------------- #
# Run all tests
[group("test")]
test *args:
bun vitest run --hideSkippedTests {{ args }}
alias t := test
# Run tests with UI
[group("test")]
test-ui *args:
bun vitest --hideSkippedTests --ui {{ args }}
alias tui := test-ui
# ---------------------------------------------------------------------------- #
# UTILITIES #
# ---------------------------------------------------------------------------- #
# Private recipe to run a check with formatted output
[no-cd]
@_run-with-status recipe *args:
echo ""
echo -e '{{ CYAN }}→ Running {{ recipe }}...{{ NORMAL }}'
just {{ recipe }} {{ args }}
echo -e '{{ GREEN }}✓ {{ recipe }} completed{{ NORMAL }}'
alias rws := _run-with-status
Justfile Patterns & Conventions
Established patterns and conventions for organizing justfiles, based on real-world usage across multiple projects.
Section Headers
Use centered ASCII art headers to organize justfiles:
# ---------------------------------------------------------------------------- #
# DEPENDENCIES #
# ---------------------------------------------------------------------------- #Standard Sections (in order)
1. DEPENDENCIES - Required tools with documentation URLs 2. ENVIRONMENT VARS - Exported environment variables 3. CONSTANTS - Glob patterns, paths, configuration values 4. COMMANDS / RECIPES - Main public recipes 5. CHECKS - Code quality and validation recipes 6. TESTS - Testing recipes 7. UTILITIES / INTERNAL HELPERS - Private helper recipes
Dependencies Section
Document required tools with URLs:
# ---------------------------------------------------------------------------- #
# DEPENDENCIES #
# ---------------------------------------------------------------------------- #
# Bun: https://bun.sh
bun := require("bun")
# UV: https://github.com/astral-sh/uv
uv := require("uv")
# Ni: https://github.com/antfu-collective/ni
na := require("na")
ni := require("ni")
nlx := require("nlx")
# Pnpm: https://github.com/pnpm/pnpm
pnpm := require("pnpm")Common tool sets:
| Ecosystem | Tools |
|---|---|
| Node.js | ni, na, nlx, pnpm, bun |
| Python | uv, ruff, pyright |
| Utilities | jq, yq, fd, rg |
Constants Section
Glob Patterns
Quote glob patterns for shell expansion:
# ---------------------------------------------------------------------------- #
# CONSTANTS #
# ---------------------------------------------------------------------------- #
GLOBS_PRETTIER := "\"**/*.{json,jsonc,yaml,yml}\""
GLOBS_SOLIDITY := "{scripts,src,tests}/**/*.sol"
GLOBS_CLEAN := "**/{.logs,bindings,build,generated}"
GLOBS_CLEAN_IGNORE := "!graph/common/bindings"Environment Variables
export LOG_LEVEL := env("LOG_LEVEL", "info")
export NODE_ENV := env("NODE_ENV", "development")Path References
JUST_DIR := justfile_dir()
CONFIG_DIR := join(justfile_dir(), "config")Recipe Groups
Use [group()] attribute for organized just --list output:
[group("checks")] # Linting, formatting, type checking
[group("codegen")] # Code generation
[group("test")] # Testing
[group("cli")] # CLI command helpers
[group("dev")] # Development utilities
[group("deploy")] # Deployment recipes
[group("print")] # Debug/print utilitiesMultiple groups per recipe:
[group("codegen")]
[group("envio")]
codegen-envio:
./codegen.shAlias Conventions
Define aliases immediately after recipe names for discoverability:
# Run all code checks
[group("checks")]
@full-check:
just _run-with-status biome-check
alias fc := full-checkStandard Aliases
| Recipe | Alias | Purpose |
|---|---|---|
full-check | fc | Run all checks |
full-write | fw | Apply all fixes |
biome-check | bc | Biome check |
biome-write | bw | Biome fix |
biome-lint | bl | Biome lint only |
prettier-check | pc | Prettier check |
prettier-write | pw | Prettier fix |
mdformat-check | mc | Markdown check |
mdformat-write | mw | Markdown fix |
ruff-check | rc | Ruff check |
ruff-write | rw | Ruff fix |
tsc-check | tc | TypeScript check |
tsc-build | tb | TypeScript build |
pyright-check | pyc | Pyright check |
knip-check | kc | Knip check |
knip-write | kw | Knip fix |
test | t | Run tests |
test-unit | tu | Unit tests |
test-ui | tui | UI tests |
build | b | Build project |
clean | c | Clean artifacts |
install | i | Install deps |
deploy | d | Deploy |
_run-with-status | rws | Status helper |
Helper Patterns
Run-With-Status Pattern
Display formatted status during multi-step workflows:
# Private recipe to run a check with formatted output
@_run-with-status recipe *args:
echo ""
echo -e '{{ CYAN }}→ Running {{ recipe }}...{{ NORMAL }}'
just {{ recipe }} {{ args }}
echo -e '{{ GREEN }}✓ {{ recipe }} completed{{ NORMAL }}'
alias rws := _run-with-statusUsage in aggregate recipes:
[group("checks")]
@full-check:
just _run-with-status biome-check
just _run-with-status prettier-check
just _run-with-status tsc-check
echo ""
echo -e '{{ GREEN }}All code checks passed!{{ NORMAL }}'
alias fc := full-checkFor-Each Pattern
Iterate over a set of items:
[private]
[script("bash")]
protocol-for-each recipe protocol:
if [ "{{ protocol }}" = "all" ]; then
just concurrent-protocols \
"just {{ recipe }} airdrops" \
"just {{ recipe }} flow" \
"just {{ recipe }} lockup"
else
just {{ recipe }} {{ protocol }}
fiConcurrent Execution Pattern
Run multiple commands in parallel:
[private]
@concurrent-protocols cmd1 cmd2 cmd3:
pnpm concurrently --group \
-n "airdrops,flow,lockup" \
-c "blue,green,yellow" \
"{{ cmd1 }}" \
"{{ cmd2 }}" \
"{{ cmd3 }}"CLI Helper Pattern
Centralize CLI tool invocation:
[private]
@cli *args:
pnpm tsx cli/index.ts {{ args }}
[group("cli")]
@export-schema:
just cli export-schemaCheck/Write Patterns
Biome (TypeScript/JavaScript)
# Check code with Biome
[group("checks")]
[no-cd]
@biome-check +globs=".":
na biome check {{ globs }}
alias bc := biome-check
# Lint code with Biome
[group("checks")]
[no-cd]
@biome-lint +globs=".":
na biome lint {{ globs }}
alias bl := biome-lint
# Fix code with Biome
[group("checks")]
[no-cd]
@biome-write +globs=".":
na biome check --write {{ globs }}
na biome lint --unsafe --write --only correctness/noUnusedImports {{ globs }}
alias bw := biome-writePrettier (JSON/YAML/Markdown)
# Check Prettier formatting
[group("checks")]
[no-cd]
@prettier-check +globs=GLOBS_PRETTIER:
na prettier --check --cache --no-error-on-unmatched-pattern {{ globs }}
alias pc := prettier-check
# Format using Prettier
[group("checks")]
[no-cd]
@prettier-write +globs=GLOBS_PRETTIER:
na prettier --write --cache --no-error-on-unmatched-pattern {{ globs }}
alias pw := prettier-writemdformat (Markdown)
# Check Markdown formatting
[group("checks")]
@mdformat-check +paths=".":
mdformat --check {{ paths }}
alias mc := mdformat-check
# Format Markdown files
[group("checks")]
@mdformat-write +paths=".":
mdformat {{ paths }}
alias mw := mdformat-writeRuff (Python)
# Check Python files
[group("checks")]
@ruff-check:
uv run ruff check .
alias rc := ruff-check
# Format Python files
[group("checks")]
@ruff-write:
uv run ruff check --fix .
uv run ruff format .
alias rw := ruff-write
# Check Python type hints
[group("checks")]
@pyright-check:
uv run pyright
alias pyc := pyright-checkTypeScript Checks
# Type check with TypeScript
[group("checks")]
[no-cd]
@type-check project="tsconfig.json":
na tsgo --noEmit --project {{ project }}
alias tc := tsc-checkFull Check/Write Pattern
Aggregate all checks with status reporting:
# Run all code checks
[group("checks")]
[no-cd]
@full-check:
just _run-with-status biome-check
just _run-with-status prettier-check
just _run-with-status tsc-check
echo ""
echo '{{ GREEN }}All code checks passed!{{ NORMAL }}'
alias fc := full-check
# Run all code fixes
[group("checks")]
[no-cd]
@full-write:
just _run-with-status biome-write
just _run-with-status prettier-write
echo ""
echo '{{ GREEN }}All code fixes applied!{{ NORMAL }}'
alias fw := full-writeDefault Recipe
Always define a default recipe that shows available commands:
# Show available commands
default:
@just --listAlternative: Run primary action by default:
# Run all checks by default
default: full-checkTest Recipes
# Run all tests
[group("test")]
@test *args:
just test-unit {{ args }}
alias t := test
# Run unit tests
[group("test")]
test-unit *args:
bun vitest run --hideSkippedTests {{ args }}
alias tu := test-unit
# Run tests with UI
[group("test")]
test-ui *args:
bun vitest --hideSkippedTests --ui {{ args }}
alias tui := test-uiBuild & Clean Recipes
# Build the project
@build:
just clean
just tsc-build
alias b := build
# Clean build artifacts
@clean globs=GLOBS_CLEAN:
bunx del-cli "{{ globs }}"
echo "✅ Cleaned build files"
# Clear node_modules
[confirm("Delete all node_modules? Y/n")]
[no-cd]
clean-modules +globs="node_modules **/node_modules":
nlx del-cli {{ globs }}Install Recipes
# Install dependencies
[no-cd]
install *args:
ni {{ args }}
# Install with conditional CI behavior
[script]
install-utils:
if [[ "$CI" == "true" ]]; then
echo "Skipping brew install in CI"
else
brew install bat delta eza fd fzf jq just rg
fiMonorepo Patterns
Module Per Package
mod client "apps/client"
mod server "apps/server"
mod shared "packages/shared"No-CD for Cross-Package Commands
[no-cd]
build-all:
just client::build
just server::buildShared Recipes via Import
# apps/client/justfile
import "../../just/shared.just"
build: shared-setup
npm run buildScript Block Patterns
Multi-line Bash
[script("bash")]
deploy chain_slug:
set -e
case {{ chain_slug }} in
mainnet)
DEPLOY_URL="https://prod.example.com"
;;
testnet)
DEPLOY_URL="https://test.example.com"
;;
*)
echo "Unknown chain: {{ chain_slug }}"
exit 1
;;
esac
curl -X POST "$DEPLOY_URL/deploy"Conditional TUI Mode
[script("bash")]
envio command tui_mode="tui_on" *args:
set -a
if [ "{{ tui_mode }}" = "tui_off" ]; then
TUI_OFF=true
fi
pnpm envio {{ command }} {{ args }}Import Organization
Settings First
import "./just/settings.just"
import "./just/base.just"
import "./just/npm.just"Devkit Pattern
# See https://github.com/sablier-labs/devkit/blob/main/just/base.just
import "./node_modules/@sablier/devkit/just/base.just"
import "./node_modules/@sablier/devkit/just/npm.just"Local Overrides Last
import "./just/base.just"
import? "./just/local.just" # Optional local overridesAttribute Combinations
Private Group Recipe
[group("internal")]
[private]
_helper:
echo "helper"Confirmed No-CD Script
[no-cd]
[script("bash")]
[confirm("Deploy to production?")]
deploy-prod:
set -e
npm run build
aws s3 sync dist/ s3://prod-bucket/Documented Group Recipe
[doc("Generate TypeScript types from GraphQL schema")]
[group("codegen")]
codegen-types:
graphql-codegenEnvironment Variable Patterns
Export with Default
export LOG_LEVEL := env("LOG_LEVEL", "info")
export NODE_ENV := env("NODE_ENV", "development")Load from .env
set dotenv-load
# Or specify path
set dotenv-path := ".env.local"Per-Recipe Environment
test-integration:
DATABASE_URL="postgres://localhost/test" npm run test:integrationError Handling
Ignore Specific Errors
cleanup:
-rm -rf dist/
-rm -rf coverage/
echo "Cleanup complete"Assert Preconditions
deploy:
{{ assert(path_exists("dist/"), "Run 'just build' first") }}
aws s3 sync dist/ s3://bucket/Graceful Fallbacks
@version:
git describe --tags 2>/dev/null || echo "v0.0.0-dev"Just Recipes Reference
Recipe definition and behavior for Just command runner.
Attributes
Attributes modify recipe behavior. Place before recipe definition.
Recipe Visibility
# Private via underscore prefix
_helper:
echo "private"
# Private via attribute
[private]
helper:
echo "also private"Grouping
[group("checks")]
lint:
npm run lint
[group("checks")]
format:
npm run formatGroups organize just --list output:
Available recipes:
default
[checks]
format
lintDirectory Control
# Don't change to justfile directory
[no-cd]
status:
git status
# Set specific working directory
[working-directory: "packages/core"]
build-core:
npm run buildScript Blocks
# Default shell script
[script]
multiline:
if [ -f "config.json" ]; then
echo "Found config"
else
echo "No config"
fi
# Specific interpreter
[script("python3")]
process:
import json
data = json.load(open("config.json"))
print(data["name"])
[script("bash")]
deploy:
set -e
npm run build
aws s3 sync dist/ s3://bucket/
[script("node")]
analyze:
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json'));
console.log(`Package: ${pkg.name}@${pkg.version}`);Confirmation
# Default confirmation prompt
[confirm]
delete-all:
rm -rf dist/
# Custom prompt
[confirm("Are you sure you want to deploy to production?")]
deploy-prod:
./deploy.sh productionDocumentation
# Comment becomes doc (default)
# Build the project
build:
npm run build
# Override with attribute
[doc("Compile TypeScript and bundle")]
build:
npm run build
# Suppress documentation
[doc]
internal-helper:
echo "hidden"Combining Attributes
# Same line (comma-separated)
[no-cd, private]
helper:
echo "helper"
# Multiple lines
[group("codegen")]
[script("bash")]
[confirm("Generate bindings?")]
codegen:
./generate.shPer-Recipe Positional Arguments
[positional-arguments]
@greet name:
echo "Hello, $1!"Recipe Parameters
Required Parameters
greet name:
echo "Hello, {{ name }}"Default Parameters
greet name="World":
echo "Hello, {{ name }}"Variadic Parameters
# One or more arguments (required)
test +files:
npm test {{ files }}
# Zero or more arguments (optional)
build *flags:
npm run build {{ flags }}Parameter with Environment Variable
# Set from env or use default
deploy env=env("DEPLOY_ENV", "staging"):
./deploy.sh {{ env }}Recipe Argument Flags (v1.46.0+)
The [arg()] attribute configures parameters as command-line options.
Long Options
Use long to accept --name style options:
# Explicit long name
[arg("target", long="target")]
build target:
cargo build --target {{ target }}
# Default to parameter name (recommended)
[arg("target", long)]
build target:
cargo build --target {{ target }}
# Usage:
# just build --target x86_64
# just build --target=x86_64Short Options
Use short to accept -x style options:
[arg("verbose", short="v")]
run verbose="false":
echo "Verbose: {{ verbose }}"
# Usage: just run -v trueCombined Long and Short
A parameter can accept both styles:
[arg("output", long="output", short="o")]
compile output:
gcc main.c -o {{ output }}
# Usage:
# just compile --output main
# just compile -o mainFlags Without Values
Use value for boolean-style flags that set a predefined value when present:
[arg("release", long, value="true")]
build release="false":
cargo build {{ if release == "true" { "--release" } else { "" } }}
# Usage:
# just build → release="false" (default)
# just build --release → release="true"Help Strings
Use help to add descriptions visible in just --usage:
[arg("target", long, help="Target architecture")]
[arg("release", long, value="true", help="Build in release mode")]
build target release="false":
cargo build --target {{ target }}$ just --usage build
Usage: just build [OPTIONS] --target <target>
Arguments:
--target <target> Target architecture
--release Build in release modeMultiple arg Attributes
Each parameter with options needs its own [arg()]:
[arg("input", long, short="i", help="Input file")]
[arg("output", long, short="o", help="Output file")]
[arg("verbose", long, short="v", value="true")]
convert input output verbose="false":
convert {{ input }} {{ output }} {{ if verbose == "true" { "-v" } else { "" } }}Pattern Constraints
Use pattern to constrain arguments to match a regular expression:
# Require numeric input
[arg('n', pattern='\d+')]
double n:
echo $(({{n}} * 2))
# Usage:
# just double 5 → valid
# just double abc → error: argument doesn't match patternUse the | operator to constrain to specific alternatives:
[arg('flag', pattern='--help|--version')]
info flag:
just {{flag}}
# Usage:
# just info --help → valid
# just info --version → valid
# just info --foo → error: argument doesn't match patternArg Attribute Syntax Summary
| Option | Description |
|---|---|
long | Accept --param (defaults to name) |
long="name" | Accept --name |
short="x" | Accept -x |
value="val" | Set this value when flag present |
help="text" | Description for just --usage |
pattern="regex" | Constrain argument to match regex |
Recipe Dependencies
Simple Dependencies
build: clean compile
echo "Build complete"
clean:
rm -rf dist/
compile:
tscDependencies with Arguments
deploy env: (build env)
./deploy.sh {{ env }}
build env:
npm run build:{{ env }}Conditional Execution
test: && lint
npm test
# lint runs only if test succeedsCommand Prefixes
| Prefix | Effect |
|---|---|
@ | Don't echo command |
- | Ignore errors |
@- or -@ | Both |
@quiet:
echo "Only output shown"
-ignore-error:
false
echo "Still runs"
@-both:
false
echo "Quiet and ignores error"Shebang Recipes
Execute with specific interpreter:
python-script:
#!/usr/bin/env python3
import sys
print(f"Python {sys.version}")
node-script:
#!/usr/bin/env node
console.log(process.version)Just Settings & Modules Reference
Configuration and module system for Just command runner.
Settings
Settings configure global behavior and must appear at the top of the justfile.
Boolean Settings
Enable with set NAME or set NAME := true:
| Setting | Description |
|---|---|
allow-duplicate-recipes | Allow later recipes to override earlier ones |
allow-duplicate-variables | Allow later variables to override earlier ones |
dotenv-load | Load .env file automatically |
dotenv-required | Error if .env file is missing |
export | Export all variables as environment variables |
fallback | Search parent directories for justfile |
ignore-comments | Don't print comments in recipe listings |
positional-arguments | Pass recipe arguments as $1, $2, etc. |
quiet | Don't echo recipe lines |
unstable | Enable unstable features (modules, script attribute) |
windows-powershell | Use PowerShell on Windows |
windows-shell | Use cmd.exe on Windows |
Value Settings
| Setting | Example | Description |
|---|---|---|
shell | ["bash", "-euo", "pipefail", "-c"] | Shell and arguments for recipes |
dotenv-filename | ".env.local" | Custom dotenv filename |
dotenv-path | "config/.env" | Custom dotenv path |
tempdir | "/tmp/just" | Temporary file directory |
working-directory | "src" | Default working directory |
Const expressions in settings (v1.46.0+):
All settings now accept const expressions:
project_name := "myapp"
src_dir := "src"
set working-directory := src_dir
set dotenv-filename := project_name + ".env"Recommended Settings
set allow-duplicate-recipes
set allow-duplicate-variables
set shell := ["bash", "-euo", "pipefail", "-c"]
set unstableShell flags explained:
-e: Exit immediately on error-u: Treat unset variables as errors-o pipefail: Pipeline fails if any command fails-c: Execute following string as command
Modules & Imports
Imports
Include another justfile's contents directly:
# Required import (error if missing)
import "path/to/file.just"
import "./just/settings.just"
# Optional import (no error if missing)
import? "local-overrides.just"Import behavior:
- Imported recipes and variables merge into current namespace
- Later definitions override earlier ones (with
allow-duplicate-*) - Relative paths resolve from importing file's directory
- Duplicate imports are deduplicated automatically
Modules
Load justfile as a submodule (requires set unstable):
# Load from foo.just or foo/justfile
mod foo
# Load from custom path
mod bar "path/to/bar.just"
mod baz "other/directory" # Looks for justfile inside
# Optional module (no error if missing)
mod? local
# Module with attributes
[private]
mod internal
[doc("Development tools")]
mod devCalling module recipes:
# Subcommand syntax
just foo build
# Path syntax
just foo::build
# From another recipe
@all:
just foo::build
just bar::testModule namespacing:
- Recipes inside modules are namespaced:
module::recipe - Variables inside modules are NOT accessible from parent
- Settings inside modules apply only to that module
- Modules can import/include other files
Module Search Paths
When using mod foo:
1. foo.just in same directory 2. foo/justfile subdirectory 3. foo/mod.just subdirectory
Just Syntax Reference
Language syntax and utilities for Just command runner.
Constants
Terminal Colors
Available globally without definition:
| Constant | ANSI Code |
|---|---|
BLACK | \e[30m |
RED | \e[31m |
GREEN | \e[32m |
YELLOW | \e[33m |
BLUE | \e[34m |
MAGENTA | \e[35m |
CYAN | \e[36m |
WHITE | \e[37m |
Text Styles
| Constant | Effect |
|---|---|
BOLD | Bold text |
ITALIC | Italic text |
UNDERLINE | Underlined text |
STRIKETHROUGH | Strikethrough text |
INVERT | Invert colors |
HIDE | Hidden text |
Reset
| Constant | Effect |
|---|---|
NORMAL | Reset all formatting |
Background Colors
| Constant | Description |
|---|---|
BG_BLACK | Black background |
BG_RED | Red background |
BG_GREEN | Green background |
BG_YELLOW | Yellow background |
BG_BLUE | Blue background |
BG_MAGENTA | Magenta background |
BG_CYAN | Cyan background |
BG_WHITE | White background |
System Constants
| Constant | Value |
|---|---|
HEX | 0123456789ABCDEF |
HEXLOWER | 0123456789abcdef |
PATH_SEP | : (Unix) or ; (Windows) |
Usage Examples
@success:
echo -e '{{ GREEN }}✓ Success!{{ NORMAL }}'
@error:
echo -e '{{ RED + BOLD }}✗ Error!{{ NORMAL }}'
@highlight:
echo -e '{{ BG_YELLOW + BLACK }}Warning{{ NORMAL }}'
@combined:
echo -e '{{ BOLD + UNDERLINE + CYAN }}Important{{ NORMAL }}'Functions
Executable Functions
# Require executable (fail if not found)
jq := require("jq")
# Returns full path: /usr/bin/jq
# Usage: invoke directly in recipes (not with interpolation)
process:
jq '.name' package.json
# Check if executable exists
has_docker := `which docker > /dev/null 2>&1 && echo "true" || echo "false"`Note: require() validates the tool exists and stores its path. Use the variable name directly (e.g., jq), not with interpolation ({{ jq }}).
Environment Functions
# Get env var (error if unset)
home := env("HOME")
# Get env var with default
log_level := env("LOG_LEVEL", "info")
# Export variable
export DATABASE_URL := env("DATABASE_URL", "postgres://localhost/dev")Path Functions
# Justfile directory (absolute path)
root := justfile_dir()
# Justfile path
justfile := justfile()
# Source directory (for imported files)
source_dir := source_directory()
source_file := source_file()
# Invocation directory (where just was called from)
invocation_dir := invocation_directory()
# Parent directory
parent := parent_directory(justfile_dir())
# Join paths
config := join(justfile_dir(), "config")
# File operations
exists := path_exists("config.json")
stem := file_stem("config.json") # "config"
name := file_name("path/config.json") # "config.json"
ext := extension("config.json") # "json"String Functions
# Case conversion
upper := uppercase("hello") # "HELLO"
lower := lowercase("HELLO") # "hello"
kebab := kebabcase("HelloWorld") # "hello-world"
snake := snakecase("HelloWorld") # "hello_world"
title := titlecase("hello") # "Hello"
# String manipulation
trimmed := trim(" hello ") # "hello"
replaced := replace("foo-bar", "-", "_") # "foo_bar"
# Quoting
quoted := quote("path with spaces") # "'path with spaces'"
shell_escaped := shell("echo 'test'")System Functions
# Operating system
os := os() # "linux", "macos", "windows"
family := os_family() # "unix" or "windows"
arch := arch() # "x86_64", "aarch64", etc.
# Number of CPUs
cpus := num_cpus()
# UUID generation
id := uuid()
# SHA256 hash
hash := sha256("content")
file_hash := sha256_file("config.json")
# Date/time
now := datetime("%Y-%m-%d")
timestamp := datetime("%s")Conditional Functions
# Error if condition false
_ := assert(path_exists("config.json"), "Config file required!")
# Conditional value
mode := if env("CI", "") != "" { "ci" } else { "local" }
# Error message
_ := error("This recipe is deprecated")Variables
Assignment
# Simple
name := "value"
# From environment
port := env("PORT", "3000")
# From shell command
version := `git describe --tags`
# Exported (available to recipes)
export NODE_ENV := "production"
# Conditional
mode := if os() == "windows" { "win" } else { "unix" }Variable Scope
- Variables defined at top level are global
- Recipe parameters shadow global variables
- Imported variables can be overridden with
allow-duplicate-variables
Backtick Evaluation
````just
Single line
version := git describe --tags
Multi-line (indented)
files := ``` find src -name "*.ts" \ | grep -v test \ | head -10
Just CLI Options
| Option | Description |
|---|---|
just --list | List available recipes |
just --list --unsorted | List in source order |
just --summary | Brief recipe list |
just --show RECIPE | Show recipe source |
just --usage RECIPE | Show recipe argument usage (v1.46) |
just --dry-run RECIPE | Print commands without running |
just --evaluate | Print all variables |
just --fmt | Format justfile |
just --fmt --check | Check formatting |
just --choose | Interactive recipe selection (fzf) |
just -f PATH | Use specific justfile |
just -d DIR | Set working directory |
Glob Patterns
Store glob patterns in variables with proper quoting:
# Quote the pattern
GLOBS_TS := "\"**/*.{ts,tsx}\""
GLOBS_JSON := "\"**/*.{json,jsonc,yaml,yml}\""
# Use in recipes
lint:
eslint {{ GLOBS_TS }}
format:
prettier --check {{ GLOBS_JSON }}Error Handling
# Fail on any error (in script block)
[script("bash")]
deploy:
set -e
npm run build
npm run test
npm publish
# Continue on error (line prefix)
cleanup:
-rm -rf dist/
-rm -rf node_modules/
echo "Cleanup attempted"
# Assert condition
check:
{{ assert(path_exists("package.json"), "Must run from project root") }}