Bash Dispatcher vs Make vs Just — A Side-by-Side Ergonomic Comparison
This article shows the ergonomic difference between:
- a Bash dispatcher (
task.sh) - a Makefile
- a Justfile
All three can run commands. All three can call shell scripts. All three can wrap external tools like pytest.
But they differ dramatically in:
- discoverability
- help output
- readability
- maintenance cost
- preset ergonomics
- ability to hold many commands cleanly
This article is the “zoomed-in” version of the small point raised in the Shell vs Make article.
1. Bash Dispatcher (“task.sh”)
This is the natural result of a “shell-composition first” philosophy.
It works, it’s explicit, and you control everything.
1.1. What it looks like
#!/usr/bin/env bash
set -euo pipefail
case "${1-}" in
deploy)
./scripts/deploy.sh
;;
deploy-only)
./scripts/deploy_only.sh
;;
test-local)
poetry run pytest -m "not network"
;;
test-network)
poetry run pytest -m "network"
;;
*)
echo "Usage: $0 {deploy|deploy-only|test-local|test-network}"
;;
esac
``
## **1.2. Advantages**
* 100% transparent (it’s just bash).
* You can do anything, conditionally, dynamically.
* Great if you only have 2–5 commands.
## **1.3. Pain points**
### **A. You must write your own help output**
Every time you add a new command, you must:
* update the case block
* update the help message
* potentially update documentation
This grows increasingly error-prone with 10+ commands.
### **B. No “automatic command listing”**
Nothing here introspects or returns:
* what commands exist
* what they do
* metadata about each command
You must maintain that manually.
### **C. Harder to read when commands grow**
With 10–15 commands, the dispatcher becomes:
* cluttered
* vertically long
* harder to scan
### **D. No standard conventions**
With Make/Just:
* people know where to look
* they know how to list tasks
* they know how to add new tasks
With bash, conventions are home-rolled.
---
---
If you want, I can also generate:
* a small demo repo layout
* a third article called **“The Minimalist Task Runner Pattern (Shell + Make + Scripts/)”**
* or a cheat sheet for “when to use what”
Just let me know.
# **2. Makefile**
Make isn’t perfect, but it solves *two* big problems instantly:
* **discoverability**
* **presets for long flag sets**
## **2.1. What it looks like**
```Makefile
.PHONY: deploy deploy-only test-local test-network help
deploy:
./scripts/deploy.sh
deploy-only:
./scripts/deploy_only.sh
test-local:
poetry run pytest -m "not network" tests
test-network:
poetry run pytest -m "network" tests
help:
@echo "Available commands:"
@echo " make deploy - build + deploy"
@echo " make deploy-only - deploy without building"
@echo " make test-local - run local-only tests"
@echo " make test-network - run network tests"
2.2. Advantages
A. You get a “task menu” naturally
Without doing much work:
make help
Or even just:
make
gives discoverability.
B. Much easier to maintain 10+ tasks
The Makefile scales better visually than a dispatcher script.
C. Perfect for presetting flags
E.g., pytest markers or long build commands.
D. Tasks are grouped and descriptive
Humans can scan them easily.
2.3. Downsides
- Make syntax is weird (tabs,
$@,$<, etc.). - Not great for complex logic (conditionals, dynamic paths).
- Not ideal for workflows you own and compose — bash is better there.
3. Justfile (Just)
Just is essentially “Make without the weird parts.”
It solves the same ergonomics problems:
- discoverability
- preset commands
- a nice task list
…but with much cleaner syntax.
3.1. What it looks like
# deploy the full site
deploy:
./scripts/deploy.sh
# deploy without building
deploy-only:
./scripts/deploy_only.sh
# local-only pytest subset
test-local:
poetry run pytest -m "not network" tests
# network subset
test-network:
poetry run pytest -m "network" tests
3.2. Advantages
A. Instant command menu
just --list
Shows everything, with descriptions.
B. Much cleaner syntax than Make
No tabs-only rules, no implicit semantics.
C. Just is designed for “command runners,” not builds
Which matches what people actually use Make for in modern projects.
3.3. Downsides
- Requires installing
just(not always available). - Slightly less universal than Make.
4. Visual Comparison (Side-by-Side)
| Feature | Bash Dispatcher | Makefile | Justfile |
|---|---|---|---|
| Discoverability | ❌ manual | ✔️ built-in | ✔️ built-in |
| Help output | ❌ manual | ✔️ trivial | ✔️ trivial |
| Maintaining 10+ commands | ❌ painful | ✔️ easy | ✔️ easy |
| Presetting external CLI flags | ⚠️ possible but clunky | ✔️ excellent | ✔️ excellent |
| Shell composition | ✔️ best | ⚠️ awkward | ⚠️ awkward |
| No extra tools needed | ✔️ yes | ✔️ yes | ❌ requires installing just |
| Ergonomics | OK for 2–5 tasks | Good for 5–20 tasks | Excellent for 5–20 tasks |
5. Conclusion
All three approaches are valid — but they shine in different regimes.
Use Bash dispatcher when:
- You have few commands (2–5)
- You control the workflow
- You want compositional clarity
- You want zero extra tools
Use Make when:
- You have 5–15 preset commands around external tools
- Commands are long, flag-heavy, or repetitive
- You want easy listing and help output
- You want a standard entrypoint
Use Just when:
- You want Make’s strengths without Make’s syntax
- You want the cleanest command-definition experience
- You have 10+ presets and want a very readable file