Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
julianobarbosa avatar

Justfile

  • 45 installs
  • 6 repo stars
  • Updated July 22, 2026
  • julianobarbosa/claude-code-skills

Create and manage command recipes for project task automation.

About

Justfile Skill. just is a command runner that saves and runs project-specific commands in a file called Justfile.

  • Templates (root + module, copy-and-adapt)
  • just language reference (variables, args, deps, conditionals, attributes)

Justfile by the numbers

  • 45 all-time installs (skills.sh)
  • +1 installs in the week ending Aug 2, 2026 (Skillselion tracking)
  • Ranked #327 of 550 CLI & Terminal skills by installs in the Skillselion catalog
  • Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/julianobarbosa/claude-code-skills --skill justfile

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs45
repo stars6
Last updatedJuly 22, 2026
Repositoryjulianobarbosa/claude-code-skills

What it does

Create and manage command recipes for project task automation.

Files

SKILL.mdMarkdownGitHub ↗

Justfile Skill

just is a command runner (not a build system) that saves and runs project-specific commands in a file called Justfile. It uses make-inspired syntax but is simpler and more portable, with none of make's idiosyncrasies (.PHONY, tab sensitivity, implicit rules, timestamp tracking).

This skill enforces a consistent house style so every Justfile looks the same across projects. The rules below are the authoritative convention; Tools/lint.ts validates the deterministic ones.

Workflow Routing

TriggerWorkflow
"create a justfile", "set up just", "add a recipe/module"Workflows/CreateJustfile.md
"migrate Makefile to just", "convert make to just"Workflows/MigrateFromMake.md
"check/lint this justfile", "is this justfile correct"Workflows/CheckJustfile.md

When to Use Just vs Make

ScenarioTool
Project task automation (build, test, deploy, lint)just
Cross-platform command runnerjust
Actual file-based build dependencies (compile .c.o)make
Legacy projects already deep in makemake (or migrate)

Common Mistakes — do NOT do these

Patterns the model often generates incorrectly. Check output against this list.

WRONGRIGHT
justfile (lowercase)Justfile (capital J)
mod docker (bare)mod docker '.justfiles/docker.just'
Module at docker.just or just/docker.justModule at .justfiles/docker.just
default:_default: (underscore required)
@just --list@just --list --unsorted (module) or --unsorted --list-submodules (root with modules)
env("NAME", "val")env_var_or_default("NAME", "val")
Module file without the three-line headerEvery file gets the full header
Module file without its own _default recipeEvery file gets its own _default
Module named after a tool (psql.just)Module named after a concern (db.just)
Tests in docker.just because they run in a containerTests in test.just — classify by purpose, not implementation
Root recipe duplicates module logicRoot shortcut delegates: build: docker-build
Ad-hoc names (run-tests, do-lint)Standard names: test, lint, build, dev, fmt, check
Relative paths in module recipes (bash tests/run.sh)Use source_directory() for absolute paths

Mandatory Rules — apply to EVERY file you create or edit

1. The root file MUST be named Justfile (capital J). 2. EVERY file (root and every .just module) MUST start with this three-line header:

   #!/usr/bin/env just --justfile
   set shell := ["bash", "-euo", "pipefail", "-c"]
   set dotenv-load := true

Use set dotenv-load := false where appropriate, but the line must always be present. 3. EVERY file MUST have _default as its first recipe:

   # List all available recipes
   _default:
       @just --list --unsorted

The root Justfile with modules uses @just --list --unsorted --list-submodules. Module files use @just --list --unsorted (no --list-submodules). 4. Section order in every file: variables → mod imports → recipes. 5. Module files MUST live at .justfiles/<name>.just — never just/, never beside the root. 6. Import modules with explicit paths: mod name '.justfiles/name.just' — never bare mod name. 7. Use env_var_or_default("NAME", "value") for variable defaults — never env(). 8. Every recipe gets a # doc comment on the line directly above it. 9. Parameterized recipes document each param: # param - description (default: value). 10. Private/helper recipes start with _. 11. Dependencies go on the definition line: build: _lint test. 12. Destructive recipes prompt for confirmation; the doc comment says "DESTRUCTIVE, prompts for confirmation". 13. Extract modules by domain concern, named after the concern (db.just) not the tool (psql.just). The root Justfile is a thin orchestrator: _default, shortcut recipes, and project-wide recipes like check/clean. 14. The root provides shortcut recipes for common workflows that delegate to modules, giving developers a flat namespace for everyday tasks. 15. Use the standard recipe vocabulary below as the public API. Never invent run-tests, do-lint, compile, format. 16. In modules, never use bare relative paths — module recipes run with the module's directory as CWD. Define root := source_directory() / ".." and reference files as {{root}}/tests/run.sh.

Standard Recipe Vocabulary

A developer should be able to run just test, just dev, or just check in any project without guessing. Use these exact names; include only the ones that apply.

RecipePurposeInclude when
devStart dev environment (server, watch, REPL)Project has a dev loop
testRun the test suiteAlways
buildBuild or compileProject has a build step
lintRun lintersLinters configured
fmtFormat codeFormatters configured
checkRun ALL quality gates (check: lint test)Always
cleanRemove build artifacts, caches, generated filesProject produces output

check is the meta-recipe — depend on the applicable gates and add format checks (cargo fmt --check, ruff format --check) as appropriate.

Namespacing by Concern

Group by domain, not tool. Classify by purpose: a test that runs in Docker is a testing recipe (test.just), not a Docker recipe. A migration that uses kubectl is a database recipe (db.just).

ConcernModuleTypical recipes
Developmentdev.justbuild, test, lint, fmt, bench
Testingtest.justrun, list, watch, coverage
Containersdocker.justbuild, push, run, compose-up
CI/CDci.justlint, deploy, release
Databasedb.justmigrate, seed, reset, dump, restore
Infrastructureinfra.justplan, apply, destroy
Kubernetesk8s.justapply, diff, rollback, logs
Documentationdocs.justbuild, serve, publish

Single-concern projects (e.g. a Go/Rust project with only build/test/lint/fmt) use one dev.just; the root still stays thin. Modules are self-contained: own variables, own _default, no cross-module recipe dependencies.

Templates & References

  • Templates (root + module, copy-and-adapt): Templates.md
  • just language reference (variables, args, deps, conditionals, attributes, functions, install): References/Syntax.md
  • Recipe fragments by project type (Terraform, Go, Python, Docker, Azure, Ansible): References/Patterns.md
  • Makefile → just migration guide: References/MakeMigration.md

Linting

After creating or editing ANY Justfile or .just module, run the structural lint and fix every failure:

bun Tools/lint.ts <project-dir>

It checks file naming, the three-line header, _default as first recipe, the --unsorted/--list-submodules flags, env_var_or_default() usage, doc comments on all recipes, explicit module import paths, and section order. Any FAIL is a bug — fix and re-run until clean. The lint cannot judge concern-based naming, self-containment, or standard-vocabulary use — verify those by inspection (see Workflows/CheckJustfile.md).

Gotchas

  • Each recipe line runs in a separate shell by defaultcd foo on one line and ls on the next runs ls in the original directory. Use a shebang recipe for multi-line scripts.
  • `set dotenv-load` loads `.env` from the justfile directory, not the invocation directory — running just from a subdirectory loads the parent's .env. Use set dotenv-path to override.
  • Backtick variables evaluate at parse time, every invocationgit_hash := \git rev-parse HEAD\` runs git on every just` call, even for unrelated recipes. Slow on large repos; move inside the recipe if not needed globally.
  • Recipe arguments don't shell-quote automaticallyjust deploy "my server" passes two args. Use set positional-arguments with "$@", or wrap as {{quote(target)}}.
  • `set shell := ["bash", "-c"]` breaks `set -euo pipefail` semantics because each line is its own -c invocation — pipefail only applies within that line. Use shebang recipes for proper fail-fast scripts.
  • `just --list` hides `_`-prefixed and `[private]` recipes but they're still callable — obscurity, not access control.
  • Cross-platform `[macos]`/`[linux]` attributes silently skip the recipe on other OSes — running just install on Windows when only [linux]/[macos] variants exist exits 0 with no error, which looks like success.
  • The lint validates structure, not behavior — a recipe can pass every check and still run the wrong command. Run just --dry-run <recipe> to verify expansion.

Related skills

CLI & Terminalworkflowpm

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.