Issue #1031
Claude Code is good at completing tasks, but it stops when it thinks it’s done. For small, well-scoped work that’s fine. For larger projects — building out a feature, getting a test suite green, or scaffolding an entire app — a single session often isn’t enough. Each attempt gets partway there, then exits.
The Ralph technique solves this by turning Claude Code into a persistent loop. Instead of one session, you get continuous iterations where each pass picks up where the last one left off.
What Ralph Is
The technique comes from Geoffrey Huntley, who named it after Ralph Wiggum from The Simpsons — the idea being that persistent, single-minded repetition eventually gets the job done. At its core, Ralph is simple: a loop that feeds Claude the same prompt over and over, each time building on the files left behind from the previous run.
The official Claude Code implementation takes this a step further. Rather than an external bash loop, it uses a Stop hook — a hook that intercepts Claude’s exit attempt and reinjects the original prompt, creating a self-referential loop inside your current session. Claude finishes, tries to stop, and the hook sends it right back to work. The implementation lives in the ralph-wiggum plugin in the official Claude Code repository.
You run the command once →
Claude works on the task →
Claude tries to exit →
Stop hook intercepts →
Same prompt gets injected again →
Claude reads its own previous work →
Claude iterates and improves →
Repeat until done
Between iterations, files and git history persist. Claude reads what it wrote last time, sees what tests failed, and adjusts. The loop handles the retry logic so you don’t have to.
Installing the Plugin
The official Ralph implementation ships as a Claude Code plugin. To install it, open Claude Code and run:
/plugin
Search for ralph-loop in the official plugin marketplace. Once installed, you get two new commands: /ralph-loop to start a loop, and /cancel-ralph to stop one.
Running Your First Loop
The basic command looks like this:
/ralph-loop "Your task description here" --completion-promise "DONE" --max-iterations 20
The --completion-promise tells the loop when to stop. When Claude outputs that exact string, the hook exits cleanly. The --max-iterations is a safety net — without it, an impossible task will run forever.
A real example for building a REST API:
/ralph-loop "Build a REST API for todos. Requirements:
- CRUD endpoints
- Input validation
- Tests with >80% coverage
- README with endpoint docs
Output COMPLETE when all tests pass." --completion-promise "COMPLETE" --max-iterations 30
Claude will implement the API, run tests, see failures, fix them, and iterate. You can walk away.
Writing Prompts That Work
The quality of your prompt determines whether the loop converges. A vague prompt leads to an agent that keeps reworking the same thing without making real progress.
Be explicit about completion. The prompt should describe exactly what “done” looks like — not just what to build, but how Claude knows it’s finished:
Implement user authentication:
1. JWT-based login and signup endpoints
2. Password hashing with bcrypt
3. All tests passing
4. No TypeScript errors
Output: <promise>AUTH_COMPLETE</promise>
Break large tasks into phases. Claude handles bounded scope better than open-ended directives:
Phase 1: User model and migration
Phase 2: Auth endpoints with validation
Phase 3: Test coverage for all auth flows
Output DONE when all three phases complete.
Add an escape hatch for when Claude gets stuck. Without one, the loop can spin endlessly on a blocker:
After 15 iterations without progress, stop and write a BLOCKED.md file
explaining what you tried and what's preventing completion.
Then output: BLOCKED
Always set --max-iterations. It’s your primary safety mechanism — the completion promise alone isn’t enough if the task turns out to be harder than expected.
Community Implementations
Two community tools extend the Ralph pattern in different directions.
frankbria/ralph-claude-code adds production-grade safeguards. It implements a dual-condition exit gate that requires both a completion indicator and an explicit EXIT_SIGNAL before stopping — preventing premature exits. It also adds rate limiting (100 calls per hour by default, configurable), a circuit breaker that detects runaway loops from repeated errors, and a semantic response analyzer that understands the difference between a successful completion and a confused one. With 566 tests and a 100% pass rate, it’s a hardened version for serious autonomous workflows.
snarktank/ralph (14k+ stars) takes a different approach entirely. Rather than running inside Claude Code, it wraps Claude Code from the outside using a bash script. Each iteration starts a fresh Claude instance with clean context — memory persists through git history, a progress.txt file, and a structured prd.json. This model suits very long-running tasks where context window accumulation becomes a problem. It also supports Amp, so the same workflow runs across different AI coding tools.
To add the snarktank marketplace to Claude Code:
/plugin marketplace add snarktank/ralph
Then install the skills:
/plugin install ralph-skills@ralph-marketplace
When to Use It
Ralph works best for tasks that have objective success criteria. Getting a test suite to green, building a feature with a clear spec, scaffolding a project from scratch — these all have concrete endpoints that Claude can work toward autonomously.
It’s less useful when the task requires judgment calls. If you’re making design decisions, choosing between architectural approaches, or debugging something subtle in production, you want Claude responding to your input, not spinning in a loop.
The combination of a good prompt, a well-defined completion signal, and a reasonable iteration limit is what makes the technique reliable. Those three pieces together define the scope clearly enough for Claude to close the loop without wandering.
Start the conversation