Skip to main content

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)

FeatureBash DispatcherMakefileJustfile
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
ErgonomicsOK for 2–5 tasksGood for 5–20 tasksExcellent 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