Claude-skill-registry just-pro
This skill provides patterns for setting up just (command runner) in projects. Use PROACTIVELY when creating build systems, setting up new repos, or when the user asks about just/justfile configuration. Covers both simple single-project repos and monorepos with hierarchical justfile modules.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/just-pro" ~/.claude/skills/majiayu000-claude-skill-registry-just-pro && rm -rf "$T"
skills/data/just-pro/SKILL.mdJustfile Skill
Build system configuration using just, a modern command runner.
Related skills:
- mise - Tool version management (includes just+mise integration patterns)
- go-pro, rust-pro, typescript-pro - Language-specific templates
Installation
# Via mise (recommended - version pinned per-project) mise use just # macOS brew install just # Linux/Windows (via cargo) cargo install just # Or prebuilt binaries: https://github.com/casey/just/releases
When to Use Just
| Scenario | Recommendation |
|---|---|
| Cross-language monorepo | just - Unified interface across packages |
| Single Go/Rust project | just or language-native (go/cargo) |
| Node.js project | npm scripts primary, just optional wrapper |
| CI/CD porcelain | just - Single entry point for all operations |
| Simple scripts | just - Better than shell scripts |
Project Patterns
Simple Repo (Single Package)
For single-language projects, create one
justfile at repo root.
# Project Build System # Usage: just --list default: @just --list # === Quality Gates === check: fmt lint test @echo "All checks passed" fmt: go fmt ./... lint: go tool golangci-lint run test: go test -race ./... build: go build -o bin/app ./cmd/app
See
references/simple-repo.just for complete templates.
Monorepo (Multiple Packages)
For monorepos, use hierarchical justfiles with the
mod system:
repo/ ├── justfile # Router - imports package modules └── packages/ ├── api-go/ │ └── justfile # Go package recipes ├── web/ │ └── justfile # TypeScript package recipes (optional) └── ops/ └── justfile # DevOps recipes
Root justfile (router):
# Monorepo Build System # Usage: just --list # Usage: just go <recipe> mod go "packages/api-go" mod web "packages/web" mod ops "ops" default: @just --list # Umbrella recipes call into modules check: (go::check) (web::check) @echo "All checks passed" setup: (go::setup) (web::setup) @echo "All toolchains ready"
Commands become:
just go check, just go lint, just web build, just ops deploy
See
references/monorepo-root.just and references/package-go.just for templates.
Recipe Patterns
Quality Gates
Always provide a single
check recipe that runs all quality gates:
# Full quality gates - run before commits check: fmt lint test coverage-check @echo "All checks passed"
Quick Check (Dev Iteration)
Fast feedback loop for development - essential checks only:
# Quick feedback loop - essential checks only check-quick: lint test @echo "Quick checks passed"
Clean Recipe
Standard cleanup for build artifacts and caches:
# Remove build artifacts and caches clean: rm -rf build/ coverage.out node_modules/.cache
Parallel Check Execution (CI)
Run package checks in parallel for faster CI:
# Run all package checks in parallel (CI optimization) check-parallel: @just api check & just web check & wait
Coverage Enforcement
Use shebang for multi-line shell logic:
# Check coverage meets 70% minimum coverage-check: #!/usr/bin/env bash set -euo pipefail go test -race -coverprofile=coverage.out ./... COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//') COVERAGE_INT=${COVERAGE%.*} [ "$COVERAGE_INT" -ge 70 ] || (echo "FAIL: Coverage ${COVERAGE}% < 70%" && exit 1) echo "PASS: Coverage ${COVERAGE}%"
The
#!/usr/bin/env bash shebang runs the entire recipe as a single shell script (variables persist across lines).
Umbrella Recipes with Module Dependencies
# Root justfile calling into modules check: (go::check) (web::check) @echo "All checks passed"
Optional Modules
For packages that may not exist in all environments:
mod? optional-package "packages/optional"
Documentation Comments
Every recipe should have a doc comment (shown in
just --list):
# Run unit tests with race detection test: go test -race ./...
Module doc comments - Comments above
mod statements also appear in just --list:
# Go API (GraphQL + Watermill) mod api "packages/api" # Next.js frontend mod web "packages/web" # PostgreSQL database mod db "packages/db"
Output of
just --list:
api ... # Go API (GraphQL + Watermill) db ... # PostgreSQL database web ... # Next.js frontend
Always add doc comments to module imports for discoverability.
Module System Details
Syntax
mod <name> "<path>" # Required module mod? <name> "<path>" # Optional module (no error if missing) mod <name> # Module at ./<name>/justfile
Working Directory
Recipes in modules run with their working directory set to the module's directory, not the root. This is the desired behavior for package-local commands.
Listing Module Recipes
just --list # Root recipes + module names just --list go # Recipes in 'go' module just --list-submodules # All recipes including submodules
Important: Use
just --list <module> not just <module> --list. The flag must come before the module name.
Calling Module Recipes
just go check # From command line (go::check) # As dependency in justfile
Integration with Language Toolchains
Go Projects
# Uses go.mod tool directive for pinned versions lint: go tool golangci-lint run # Auto-fix linting issues (chains goimports to fix imports after modernize changes) fix: go tool golangci-lint run --fix go tool goimports -w .
Why chain goimports? The
modernize linter may change code (e.g., fmt.Errorf() → errors.New()) without updating imports, breaking builds. Running goimports after --fix resolves this.
TypeScript/Node Projects
Two approaches:
Option A: Thin wrapper (recommended for consistency)
# packages/web/justfile check: npm run check lint: npm run lint test: npm test
Option B: Direct delegation from root (simpler)
# Root justfile - no web module ts-web-check: cd packages/web && npm run check
Rust Projects
check: fmt lint test @echo "All checks passed" fmt: cargo fmt --all lint: cargo clippy -- -D warnings test: cargo test
Mise Integration
When a project uses mise for tool version management, just recipes should use
mise exec to ensure pinned versions are used regardless of developer shell setup.
See the
skill for full mise setup including shell config, direnv integration, and project mise
.mise.toml patterns.
Shell Override (Recommended)
# All recipes automatically use mise-pinned tools set shell := ["mise", "exec", "--", "bash", "-c"] build: npm run build test: go test ./...
Graceful Degradation
For repos where mise is optional:
set shell := ["bash", "-c"] # Use mise if available, otherwise fall back to PATH _exec cmd: #!/usr/bin/env bash if command -v mise &>/dev/null; then mise exec -- {{cmd}} else {{cmd}} fi build: (_exec "npm run build") test: (_exec "go test ./...") lint: (_exec "golangci-lint run")
Note: No
.mise.toml check needed - mise traverses parent directories automatically.
Why This Matters
| Developer Setup | Without mise exec | With mise exec |
|---|---|---|
| Has direnv + mise | Correct versions | Correct versions |
| Has mise activate | Correct versions | Correct versions |
| Fresh clone, no setup | System tools (wrong version) | Pinned versions |
| CI/CD | Needs activation step | Just works |
Recommendation: Use the shell override for team repos. Use graceful degradation for open source where mise adoption varies.
Caveats
Failure mode: Shell override + mise not installed = cryptic "could not find shell" error. Use graceful degradation for open source.
First clone: Contributors must run
mise trust to allow the repo's config:
setup: mise trust mise install @echo "Toolchain ready"
Security Auditing
All language templates include consistent audit recipes:
| Recipe | Purpose |
|---|---|
| Check for vulnerabilities (informational) |
| Auto-fix where possible (npm only) |
| CI-friendly (strict, production deps only) |
Language tools:
| Language | Tool | Installation |
|---|---|---|
| Node/npm | | Built-in |
| Go | | |
| Rust | | |
Reference Templates
Load the appropriate template based on project structure:
| Template | Use Case |
|---|---|
| Single-package repositories |
| Monorepo root router |
| Go package in monorepo |
| TypeScript package in monorepo |
| Rust package in monorepo |
Note: Reference files use
.just extension for organization. Actual project files must be named justfile (no extension) or .justfile.