Skip to main content
How to Write Loops in Claude Code

How to Write Loops in Claude Code

· 9 min read
James Daniel Whitford
Software engineer and technical writer

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
cd claude-code-loops-demo
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 <prompt>Runs every 5 minutes
/loop <prompt>Claude chooses the interval
/loopUses .claude/loop.md if it exists

/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
# make any small edit to src/routes/users.js
git add . && git commit -m "update users route"
git push origin fix-users-route
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 <condition>

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 /goal are primitives. You write the prompt, you define the condition. For more complex work there is a third option: describe the outcome you want and ask Claude to design the loop structure itself.

The demo repo has three failing tests, one per route. You could fix them all in one PR. Or you could ask Claude to handle them properly: one PR per fix, each reviewed before the next one starts, with each fix running in its own worktree while you do other work.

When to use it: multi-stage work where each step depends on the previous one. Write, review, fix, merge, repeat. You want Claude to own the whole sequence, not just one part of it.

How to ask

Describe the outcome, not the implementation. Ask Claude what it would do before asking it to do anything:

I want to fix the three failing tests one at a time, each on its own PR,
with a review pass on each before merging. Run each fix in its own worktree
so the threads don't interfere with each other or with my working directory.
Can you design a workflow that handles that automatically? What would it look like?

Asking for worktrees matters here. Without them, parallel threads all write to the same working directory and step on each other. With worktrees, each thread gets its own isolated branch and its own checkout. You can keep working while the loops run, and nothing lands on your main branch until each PR merges cleanly.

Claude proposes a structure. Read it. Push back on anything that seems off. Then:

That looks good. Build it and run it.

Claude opens a worktree for the first fix, files a PR, reviews it in a separate thread, addresses comments, merges when clean, and starts the next.

Run parallel sessions with worktrees

Further reading: Dynamic workflows

Building your own loops

Every loop has three parts:

  1. Trigger: a time interval (/loop 5m), a completed turn (/goal), an external event like a PR comment
  2. Prompt: what Claude does or checks each iteration
  3. Stop condition: you press Esc, a model confirms the condition, or the task completes

The starting point is always the same: look at what you do after your last prompt. That sequence is the loop. Ask Claude if it can do the next step. Then the one after that.

The three levels in this guide follow that progression. /loop hands off one repeating check. /goal hands off one task with a finish line. Asking Claude to design the workflow hands off the whole thing, structure included.

When you're not sure which level you need, ask Claude: "Is it possible to make a workflow that does X? What would it look like?" Its answer tells you whether you need a simple loop, a goal, or something it designs itself.

The .claude/loop.md file in the demo repo is a starting point for level one. Replace the prompt with whatever you want Claude watching.

For loops that run when your machine is off, see routines. For agents that communicate with each other in real time, see agent teams.

Bonus: loop prompts to try

These are ready to paste into .claude/loop.md or use directly with /loop.

Watch open PRs for review comments and address them:

/loop 5m
Check all open PRs with gh pr list.
For each one, read new review comments with gh pr view <number> --comments.
If there are unaddressed comments, fix the code in src/, commit, and push.
Do not modify tests. Do not open new PRs.

Morning standup: summarise what merged overnight:

/loop 24h
Run gh pr list --state merged --limit 10.
For each PR merged in the last 24 hours, summarise what changed in one sentence.

Keep working until all tests pass and the build is clean:

/goal npm test and npm run build both exit clean

Daily PR health check:

/loop 24h
Run gh pr list --state open.
For each PR, check CI status with gh pr checks <number>.
Report which are ready to merge, which are failing, and which have had no activity in over 3 days.

Fix lint errors until the codebase is clean:

/goal npm run lint exits with no errors

Keep working on a large migration until it compiles:

/goal npm run build exits with no errors and no TypeScript warnings

Multi-module refactor, one PR per module, each reviewed before the next starts:

Add input validation to each file in src/routes/ one at a time.
One PR per file, review pass before merging, each in its own worktree.
Can you design a workflow for that and run it?

About the author

James Daniel Whitford
James Daniel WhitfordSoftware engineer and technical writer

James Daniel Whitford is a software engineer and technical writer at Ritza. He writes about developer tooling, AI agents, and full-stack web development, and contributes hands-on tool comparisons to TechStackups.