Your Justfile Is Your Repo's API
Ask your agent to run the tests in a repo it has never seen before and watch what happens. It’s gonna load so many things into the context to try to figure it out, digging through the repo to find the right command and what framework you’re using.
What if you could standardize on a way to run the tests no matter the language or the framework?
just test
It’s a statement. It’s an interface. Sure, it’s a shortcut.
I wrote about Just as a command runner back in March.
After months of using it on a daily basis with agent-driven work, I’m here to tell you that it’s an incredibly useful cog in the wheels of complexity.
Your justfile can become what is essentially an operational API for your repository. You use it, your agents use it, the CLI calls it. Everything underneath it you can change as much as you want, as long as the command keeps its promise.
The Command Is the Contract
An API lets a caller ask a system to do something without understanding every detail inside it. A justfile does exactly that for application operations.
When I run just test, I’m not asking Just to test the software. I’m asking the repository to perform its official test operation. Today that recipe might be:
test:
lsm exec -- uv run pytest
Those few words hide several decisions. The project uses uv, tests run through pytest, secrets come through lsm.
Whoever calls that doesn’t need to rebuild or reconstitute any past decisions that went into that command. And the recipe can change as long as what happens when I run the command doesn’t. This is what makes adding Just to your application a proper interface and not just an alias.
Well, actually, if I were in charge of making a motto, I think the tongue-in-cheek version should be just an alias.
The Justfile Connects the Tooling Layers
Modern repos can have several tools doing different jobs, and that’s fine.
- Mise can pin your Python version, and it can operate as your task runner.
- uv manages the Python environment and runs commands inside it.
- LSM is more of a me thing, but it provides secrets when an operation needs them.
- The application CLI holds the actual business behavior.
- Just If you’re already using Mise as your task runner, you may not need Just at all.
Modules Turn Commands Into Namespaces
Once a project has more than a handful of operations, one flat list becomes a junk drawer. Just supports modules, so the root justfile can declare:
mod blog
mod links
mod db
mod books
Each module owns its related recipes, and the result reads like a small command-line app:
just blog status
just db backup
just books unresolved
The manual describes module recipes as subcommands. The hierarchy helps humans discover the interface, and it gives agents a predictable way to narrow down the operation they want. It also kills the naming nonsense of flattening every domain and action into one giant alphabetical list. The namespace carries the context.
Hide Plumbing, Not Consequences
An API should make a system easier to use. It should not disguise what the system does.
A recipe can absolutely hide the auth wrapper, the environment setup, and the CLI invocation. It should never make a destructive production operation look like an innocent local check. Good recipe names describe intent, so the caller knows which commands read, write, publish, restore, or preview. Dangerous workflows still need real validation, permissions, confirmations, and backups.
A justfile is an interface. It is not a place to dump everything.
A Few Rules to Follow
Sometimes it’s obvious.
Name recipes after intent. test, backup, publish, status. Not test-pytest-with-lsm — it’s hard to tell what that actually does.
Keep one canonical path. If just test, Mise, a shell script, and the README all run different tests, you have four contracts and no interface.
Pass through useful arguments. just books fetch --dry-run preserves application options without a new recipe for every flag.
Make discovery useful. Comments plus modules turn just --list into documentation.
Keep recipes thin. Branching rules, error handling, and database logic belong in tested application code.
The Boring Boundary Wins
Just still does the simple thing I liked back in March. It saves project-specific commands and runs them as recipes. The manual calls it a command runner, not a build system, and that’s correct.
The bigger value shows up when everyone agrees to call the same recipes. Humans stop memorizing setup. Agents stop reconstructing commands. CI and local development share an entry point. The tools underneath can churn without dragging things down.
Congratulations, that’s your application as an API.
Sources
- Just Programmer’s Manual — defines Just as a project-specific command runner and documents recipes, arguments, listing, and multi-file organization.
- Just modules documentation — documents
modstatements and invoking module recipes as subcommands.
I’d appreciate a follow. You can subscribe with your email below. The emails go out once a week, or you can find me on Mastodon at @[email protected].