Create or improve Makefiles with minimal complexity. Templates available: base, python-uv, python-fastapi, nodejs, go, chrome-extension, flutter.
Create Makefiles that are simple, discoverable, and maintainable.
uv run - Always run Python commands via uv run for venv contextFor new projects, use the appropriate template:
| Project Type | Template | Complexity |
|---|---|---|
| Any project | templates/base.mk | Minimal |
| Python with uv | templates/python-uv.mk | Standard |
| Python FastAPI | templates/python-fastapi.mk | Full-featured |
| Node.js | templates/nodejs.mk | Standard |
| Go | templates/go.mk | Standard |
| Chrome Extension | templates/chrome-extension.mk | Modular |
| Flutter App | templates/flutter.mk | Modular |
The chrome extension template uses a modular structure:
Makefile # Main file with help + includes
makefiles/
colors.mk # ANSI colors & print helpers
common.mk # Shell flags, VERBOSE mode, guards
build.mk # Build zip, version bump, releases
dev.mk # Test, lint, clean, install
Copy from templates/chrome-extension-modules/ to your project's makefiles/ directory.
Key features:
build-release - Version bump menu (major/minor/patch) + zip for Chrome Web Storebuild-beta - (Optional) GitHub releases with gh CLIdev-test / dev-test-e2e - Vitest + Playwright testingVERBOSE=1 make <target> - Show commands for debuggingMakefile # Main file with help + includes
makefiles/
colors.mk # ANSI colors & print helpers
common.mk # Shell flags, VERBOSE mode, guards
dev.mk # Setup, run simulator/device, devices, clean
build.mk # iOS/Android builds (IPA, APK, AAB)
deploy.mk # TestFlight upload
lint.mk # Dart analyze & format
Copy from templates/flutter-modules/ to your project's makefiles/ directory.
Key features:
flutter-run-ios auto-boots simulator and waits for itflutter-run-android auto-launches emulator and waits for itflutter-run-device auto-detects or uses FLUTTER_IOS_DEVICE / FLUTTER_ANDROID_DEVICEflutter-build-ipa + flutter-deploy-testflight full iOS release workflowflutter-lint FIX=true Dart formatting with FIX patternVERBOSE=1 make <target> show commands for debuggingUse kebab-case with consistent prefix-based grouping:
# Good - consistent prefixes (hyphens, not underscores)
build-release, build-zip, build-clean # Build tasks
dev-run, dev-test, dev-lint # Development tasks
db-start, db-stop, db-migrate # Database tasks
env-local, env-prod, env-show # Environment tasks
# Internal targets - prefix with underscore to hide from help
_build-zip-internal, _prompt-version # Not shown in make help
# Bad - inconsistent
run-dev, build, localEnv, test_net
build_release, dev_test # Underscores - don't use
Name targets after the action, not the tool:
# Good - describes what it does
remove-bg # Removes background from image
format-code # Formats code
lint-check # Runs linting
# Bad - names the tool
rembg # What does this do?
prettier # Is this running prettier or configuring it?
eslint # Unclear
For projects distributed as pre-built binaries via GitHub Releases:
GITHUB_REPO ?= owner/repo
OS := $(shell uname -s | tr '[:upper:]' '[:lower:]')
ARCH := $(shell uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/')
.PHONY: install-cli
install-cli: ## Download and install CLI from latest GitHub release
@RELEASE=$$(curl -fsSL https://api.github.com/repos/$(GITHUB_REPO)/releases/latest | grep tag_name | cut -d'"' -f4); \
echo "Installing $$RELEASE for $(OS)/$(ARCH)..."; \
curl -fsSL -o ~/.local/bin/cli \
"https://github.com/$(GITHUB_REPO)/releases/download/$$RELEASE/cli-$(OS)-$(ARCH)"; \
chmod +x ~/.local/bin/cli
Key considerations:
~/.local/bin (user-writable, in PATH)uv run for Python# Good - uses uv run with ruff (modern tooling)
dev-check:
uv run ruff check src/ tests/
uv run ruff format --check src/ tests/
uv run mypy src/
dev-format:
uv run ruff check --fix src/ tests/
uv run ruff format src/ tests/
# Bad - relies on manual venv activation
dev-format:
ruff format .
uv sync (not pip install)env-install:
uv sync # Uses pyproject.toml + lock file