TJF.lol
Tech & TomfooleryMakefiles and AI Coding Agents
March 9, 2026
make was written in 1976 to automate compiling C programs. Fifty years later, I’ve found it to be a useful tool for augmenting the AI coding agents I use. Claude Code has been a daily-driver tool for me for months now, and I now keep a Makefile at the root of every project I work on, even though none of them are C/C++ projects.
I have my agent save common patterns as Make targets, and the Makefile becomes a repository of actions that persists across sessions. I’ve found a well-maintained Makefile reduces the daylight between the agent’s actions and my intentions. Here’s why I think this approach works so well:
Increased confidence. When my agent invokes a pre-vetted Make target, I know the command is correct, either because I wrote it myself or because the agent ran it in the past and I’ve validated the results. I can guarantee it’s pulling the right data by pointing it at a specific SQL query. I can guarantee it’s deploying in the correct way because the deploy steps are encoded in the Makefile. This is a level of confidence I don’t have when the agent is improvising commands from scratch each time.
Reduced back-and-forth. I have targets for everything I do more than once: querying databases, deploying services, tailing logs, checking service health, sending notifications, generating reports. When I start a new Claude Code session, the agent reads the Makefile and has full context on every operation available in that project. Instead of explaining what I want done and hoping the agent remembers the right incantation, I point it at a target and it executes. This saves me time and reduces my agent’s token consumption.
Well-understood by AI models. AI models were trained on millions of Makefiles across decades of open source software. make <target> is one of the most universal patterns in building software, and language models already know how to work with it.
Persistence between sessions. Coding agents don’t retain context between sessions. Any type of command I might want to run either needs to be re-learned each time, or saved somewhere. A Makefile helps solve this by encoding those commands in a file. This is a similar benefit to a skills directory, but with the added bonus of executability.
Minimal setup. Claude Code can already run shell commands, and it already knows how to use Make. Adding a Makefile to your repo gives your agent a catalog of actions. This works equally well with Codex, Cursor, or any agent that can execute a shell command. When you outgrow Make, the targets translate naturally into shell scripts or a more structured CLI tool.
I can run the commands too. I can just as easily type make migrate-db as Claude. This means I can easily test the individual commands. Claude Code can combine them with bash incantations as it sees fit, and so can I if needed.
As an example, here’s a Makefile from a full-stack web app built on Cloudflare Workers. When I tell Claude Code to deploy, it runs make deploy, which runs deploy-api and then deploy-web in sequence. When I ask it to migrate the database in production, it knows to use make db-migrate-prod instead of make db-migrate. In essence, the Makefile is the control panel for the project.
-include .env
export
.PHONY: dev deploy deploy-api deploy-web install typecheck db-migrate db-migrate-prod test-unit test-e2e
install:
npm install
typecheck:
cd packages/shared && npx tsc --noEmit
cd apps/api && npx tsc --noEmit
cd apps/web && npx tsc --noEmit
dev:
@echo "Starting API (port 8787) and Web (port 4321)..."
@trap 'kill 0' EXIT; \
cd apps/api && npx wrangler dev & \
cd apps/web && npm run dev & \
wait
deploy-api:
cd apps/api && npx wrangler deploy --env production
deploy-web:
rm -rf apps/web/dist
npm run build --workspace=apps/web
npx wrangler pages deploy apps/web/dist --project-name my-app --commit-dirty=true
deploy: deploy-api deploy-web
db-migrate:
cd apps/api && npx wrangler d1 migrations apply my-db --local
db-migrate-prod:
cd apps/api && npx wrangler d1 migrations apply my-db --remote
test-unit:
npm run test:unit
test-e2e:
npm run test:e2e
Make requires tabs for indentation and doesn’t ship with Windows. If your project commands involve complex dependency graphs or conditional logic, you’ll outgrow a Makefile quickly. Related tools like scripts in a package.json or a directory of .sh files offer similar benefits and may be a better fit depending on your setup.
Makefiles have been encoding project-specific commands for half a century. That they also happen to work so well as an interface for AI agents is a happy accident of good design. If you’re using a coding agent, try adding one.