How to Write Loops in Claude Code | Tech Stackups
Skip to main content<br>Boris Cherny, the creator of Claude Code, said this in a recent interview: "I don't prompt Claude anymore. I have loops that are running. They're the ones prompting Claude and figuring out what to do. My job is to write loops."
Anthropic put it a different way in a recent research piece: agents can now run code themselves and delegate hours of work to other agents. The human role is shifting from doing to designing the loop.
The shift happens when you start moving work into the loop.
You're already running a loop
Think about what you do after Claude finishes a task:
Run the tests
Check the output
Push a commit
Open a PR
Wait for review comments
Copy-paste them back into Claude
Address them
Merge
That sequence is a loop. You're the controller, carrying context from step to step, deciding when to go again, deciding when to stop.
The loop paradigm is you shifting those actions back to the agent.
You don't need custom tooling or orchestration frameworks. The primitives are already in Claude Code: /loop, /goal, and dynamic workflows. This guide shows you how to use each one.
The demo repo
Our demo repo is a small broken Express API with three routes and three failing tests. Each section of this guide uses it to demonstrate a loop pattern. You don't need it to follow along. The concepts apply to any codebase. But if you want to try the commands yourself, fork it, clone it, and install:
git clone https://github.com/YOUR_USERNAME/claude-code-loops-demo<br>cd claude-code-loops-demo<br>npm install
1. Watch a PR with /loop
What it is: /loop runs a prompt on a repeating schedule. Claude wakes up, does something, reports back, and goes again. You stop it when you're done.
The syntax:
SyntaxBehaviour/loop 5m Runs every 5 minutes/loop Claude chooses the interval/loopUses .claude/loop.md if it exists<br>/loop never stops itself. You press Esc.
Put your standing instructions in .claude/loop.md. Bare /loop picks that file up automatically. You can edit it between iterations without stopping the loop.
When to use it: watching a PR for comments, monitoring CI, polling a queue, summarising Slack mentions overnight. Anything where you want Claude checking something on a cadence while you do other work.
When a teammate leaves a review comment, you read it, copy-paste it into Claude, Claude fixes it, you push, and you wait for the next one. That is the loop. /loop runs it without you.
Try it
Open Claude Code in the demo repo and start the PR watcher:
/loop
This uses .claude/loop.md in the repo, which tells Claude to check the open PR for new review comments every few minutes and address any it finds.
Make a small change, push a branch, and open a PR:
git checkout -b fix-users-route<br># make any small edit to src/routes/users.js<br>git add . && git commit -m "update users route"<br>git push origin fix-users-route<br>gh pr create --title "Update users route" --body ""
Go to GitHub and leave a review comment on the PR. Something like: "The POST /users route should return 201, not 200."
The loop picks it up, fixes src/routes/users.js, pushes the change, and waits for the next comment. Leave another. Watch it iterate.
Press Esc when you're done reviewing.
Worktrees: run the loop without blocking your main branch
Once you have a loop watching a PR, you want it isolated so the loop's changes don't land in your working directory while you're doing other things. --worktree starts Claude in a fresh git checkout on its own branch:
claude --worktree pr-watcher
Everything the loop does stays in that worktree. Your main branch is untouched. Merge when you're happy, delete the worktree if you're not.
Run parallel sessions with worktrees
Further reading: Run a prompt repeatedly with /loop
2. Run until done with /goal
What it is: /goal sets a condition and Claude keeps working until a separate model confirms it is met. The evaluator is a different instance from the worker, so Claude cannot mark its own homework done.
The syntax:
/goal
Claude starts immediately. After each turn, the evaluator checks the condition and returns a reason. Run /goal with no arguments to check status. Run /goal clear to stop early.
/loop fires on a time interval and you stop it. /goal fires after each completed turn and stops itself.
When to use it: fix all failing tests until CI passes, migrate a module until the build is clean, work through a backlog until the queue is empty. Any task with a clear measurable end state.
Try it
After the PR loop has addressed the review comments, merge the PR and hand off the remaining test failures:
/goal all three tests in tests/ pass and npm run lint exits clean
Write conditions with one measurable end state and a stated check. Claude edits the broken routes, runs the tests after each change, and stops when everything passes.
Further reading: Keep Claude working toward a goal
3. Ask Claude to design the loop
/loop and...