"That's the beauty of Ralph - the technique is deterministically bad in an undeterministic world."
A complete, ready-to-use system for autonomous, incremental software development using AI agents in a continuous loop.
The Ralph Wiggum Technique enables AI coding agents to build complex applications systematically across multiple sessions/context windows. Instead of trying to build everything at once, the agent works on ONE feature at a time, tests it thoroughly, and leaves clear documentation for the next session.
Why "Ralph Wiggum"? Named after The Simpsons character, the technique embraces simplicity over cleverness. Like Ralph showing up every day with innocent enthusiasm, this approach takes small, methodical steps rather than trying to solve everything at onceβand that predictability is exactly what makes it work.
π Want to see it in action? Check out EXAMPLE_OUTPUT.txt for a complete real-world iteration showing Ralph selecting a feature, implementing it, and committing changes.
Based on:
- Matt Pocock's YouTube video: "Ship working code while you sleep with the Ralph Wiggum technique"
- Dex & Geoffrey Huntley: "Ralph Wiggum Methodology - Bash Loop vs. Anthropic Plugin" - Deep dive into deterministic bash-loop approach vs auto-compaction
- Anthropic's research on long-running agent harnesses
- Geoffrey Huntley's Ralph Wiggum loop pattern
Note: This is a complete production toolkit for building applications across multiple sessions. If you're looking for the official Claude Code plugin for in-session loops, that's differentβit's great for iterative refinement within a single session. This implementation focuses on systematic multi-session development with git integration, structured PRDs, dependency tracking, and safety features.
This kit contains everything you need:
| File | Purpose |
|---|---|
The Ralph Wiggum Technique.md |
Comprehensive explanation of the technique |
AGENT_PROMPT.md |
Ready-to-use prompt for coding agents |
INITIALIZER_PROMPT.md |
Prompt for first-time project setup |
prd.json.template |
Example feature list structure |
ralph.sh |
Bash script to orchestrate the agent loop |
init.sh.template |
Example development environment script |
EXAMPLE_OUTPUT.txt |
Real example of a complete Ralph iteration |
README.md |
This file - quick start guide |
Ralph lives in /code/ralph as your toolkit directory. To use it in other projects, create a wrapper script:
# In your project directory (e.g., ~/code/my-project/)
# Create ralph-local.sh
cat > ralph-local.sh << 'EOF'
#!/bin/bash
# Wrapper to run Ralph with correct paths
RALPH_DIR="$HOME/code/ralph"
AGENT_PROMPT_FILE="$RALPH_DIR/AGENT_PROMPT.md" \
"$RALPH_DIR/ralph.sh" "$@"
EOF
chmod +x ralph-local.shThen run Ralph in your project:
./ralph-local.sh # Human-in-the-loop mode
RUN_MODE=continuous ./ralph-local.sh # Continuous modeOr add to your shell profile (~/.zshrc or ~/.bashrc):
export RALPH_DIR="$HOME/code/ralph"
alias ralph="AGENT_PROMPT_FILE=$RALPH_DIR/AGENT_PROMPT.md $RALPH_DIR/ralph.sh"Then use ralph from any project directory!
-
Describe your project in a text file:
Build a todo list web app with: - Add/edit/delete todos - Mark as complete - Filter by status - Persist to local storage -
Run the initializer agent:
- Open your AI agent (Cursor, Claude, etc.)
- Give it
INITIALIZER_PROMPT.md+ your requirements - Let it create
.ralph/directory withprd.json,progress.txt,init.sh, and project structure
-
Start the Ralph loop:
Human-in-the-Loop (Recommended for learning):
./ralph.sh
Runs one iteration, pauses for review, then you run it again.
Continuous AFK Mode:
RUN_MODE=continuous ./ralph.sh
Runs continuously until all features complete.
-
Watch it build: The agent will implement features one by one, test each thoroughly, and commit progress.
-
Create
.ralph/directory and ignore it:mkdir -p .ralph echo ".ralph/" >> .gitignore
-
Manually create
.ralph/prd.jsonusingprd.json.templateas reference -
Create empty
.ralph/progress.txt:echo "=== Ralph Wiggum Progress Log ===" > .ralph/progress.txt echo "Started: $(date)" >> .ralph/progress.txt
-
(Optional) Create
.ralph/init.shif you need automated dev server startup:# Copy and adapt the template cp init.sh.template .ralph/init.sh chmod +x .ralph/init.sh # Edit to match your project's needs
Note: Most existing projects don't need this - the agent can use your existing npm/pnpm scripts.
-
Ensure git is initialized:
git init git add . git commit -m "Initial commit"
-
Start the loop:
# Human-in-the-loop (one iteration at a time) ./ralph.sh # OR continuous mode (runs until complete) RUN_MODE=continuous ./ralph.sh
Phase 1: Initialization (first run only)
- Analyzes requirements
- Creates comprehensive feature list (
prd.json) - Sets up dev environment
- Configures testing infrastructure
Phase 2: Incremental Development (continuous loop)
1. Get bearings (read git log, progress, PRD)
β
2. Test existing functionality
β
3. Select ONE feature to implement
β
4. Implement with clean code
β
5. Test thoroughly (unit + e2e + browser automation)
β
6. Update .ralph/prd.json (mark as passing)
β
7. Log to .ralph/progress.txt
β
8. Git commit
β
9. Repeat until all features pass
.ralph/prd.json - The Feature List (Schema v2.0)
{
"schema_version": "2.0",
"features": [
{
"id": "001",
"type": "feature",
"category": "functional",
"priority": "high",
"description": "User can add a new todo item",
"steps": [
"Click 'Add Todo' button",
"Enter todo text",
"Press Enter or click Save",
"Verify todo appears in list"
],
"estimated_complexity": "medium",
"depends_on": [],
"passes": false, // Agent changes to true when complete
"iterations_taken": 0,
"blocked_reason": null
}
]
}New Schema Features:
type: Feature type -feature,bug,refactor, ortestdepends_on: Array of feature IDs that must complete firstestimated_complexity: Size estimate -small,medium, orlargeiterations_taken: Automatically tracked by agentblocked_reason: Explanation if feature is blocked
.ralph/progress.txt - The Agent's Memory
- What was worked on
- What challenges were faced
- What decisions were made
- What's next
.ralph/init.sh - Quick Environment Setup (Optional)
- Installs dependencies
- Starts dev server
- Used by agent to test features
- Only needed for new projects or complex setups
- Existing projects can use standard npm/pnpm scripts instead
Note: All Ralph workflow files are stored in .ralph/ directory which is gitignored to prevent accidental commits.
For new projects:
I want to use the Ralph Wiggum Technique to build [your project].
Here are my requirements:
[paste your requirements]
Please read and follow: INITIALIZER_PROMPT.md
For coding iterations:
Continue implementing features using the Ralph Wiggum Technique.
Please read and follow: AGENT_PROMPT.md
Two Modes Available:
1. Human-in-the-Loop Mode (Default)
./ralph.sh- Runs ONE iteration then stops
- Perfect for learning, debugging, and complex features
- Review changes after each iteration
- Run again when ready:
./ralph.sh
2. Continuous AFK Mode
RUN_MODE=continuous ./ralph.sh- Runs until all features complete or max iterations reached
- Great for overnight runs
- Autonomous operation
Configure AI Agent:
Edit the top of ralph.sh to set your preferred agent:
AI_AGENT_MODE=claude(default)AI_AGENT_MODE=manual(interactive prompts)AI_AGENT_MODE=cursor(Cursor CLI)AI_AGENT_MODE=custom(your own command)
- Break features into atomic, testable pieces
- Use browser automation for UI testing
- Run type checking and linters
- Write descriptive commit messages
- Keep features small (implementable in one session)
- Test thoroughly before marking complete
- Try to implement multiple features at once
- Mark features complete without testing
- Delete or modify feature descriptions
- Leave code in a broken state
- Skip git commits
- Assume code works without verification
Ralph includes automatic error recovery:
Automatic Rollback:
# Enabled by default
ROLLBACK_ON_FAILURE=true ./ralph.sh- Automatically runs tests after each commit
- Rolls back the commit if tests fail
- Marks feature as potentially blocked
Verification Tests:
# Enabled by default
VERIFY_BEFORE_COMPLETE=true ./ralph.sh- Runs code quality gates: formatting, linting, type checking, tests
- Only accepts commits if all quality gates pass
- See "Code Quality Gates" section below for details
Disable for manual control:
ROLLBACK_ON_FAILURE=false VERIFY_BEFORE_COMPLETE=false ./ralph.shRalph enforces strict code quality standards before marking features complete. When VERIFY_BEFORE_COMPLETE=true (default), the following checks run automatically:
# Auto-fix enabled by default
AUTOFIX_PRETTIER=true ./ralph.sh- Checks prettier/black/gofmt formatting
- Auto-fixes formatting issues before verification (if enabled)
- Status: Blocks completion if formatting fails
- Fix:
npm run formatorprettier --write .
# Runs automatically
npm run lint- Checks for code quality issues, bugs, style violations
- Status: ALWAYS BLOCKS feature completion
- Linting is NOT optional - errors must be fixed
- Fix: Address linting errors before marking feature complete
# Runs automatically if TypeScript detected
npm run typecheck # or tsc --noEmit- Validates TypeScript types, Python type hints, etc.
- Status: ALWAYS BLOCKS feature completion if configured
- Zero type errors required
- Fix: Resolve type errors before marking feature complete
# Runs automatically if tests exist
npm test- Runs full test suite
- Status: ALWAYS BLOCKS feature completion if tests fail
- Existing tests must not break
- New features should have test coverage
- Fix: Fix failing tests before marking feature complete
# Default: auto-fix prettier formatting before checks
AUTOFIX_PRETTIER=true ./ralph.sh
# Disable auto-fix (will still check formatting)
AUTOFIX_PRETTIER=false ./ralph.sh
# Disable all verification (not recommended)
VERIFY_BEFORE_COMPLETE=false ./ralph.shRalph provides a clear summary after running checks:
Quality Gate Summary:
β
Formatting
β
Linting
β
Type Checking
β
Tests
β
ALL QUALITY GATES PASSED
Or if failures occur:
Quality Gate Summary:
β
Formatting
β Linting
β Type Checking
β
Tests
β QUALITY GATES FAILED - Feature cannot be marked complete
Important: Features CANNOT be marked as "passes": true in prd.json until ALL quality gates pass.
Features can now declare dependencies:
{
"id": "005",
"description": "User can delete a todo",
"depends_on": ["001", "003"], // Needs create and display first
"passes": false
}The agent will automatically skip features with unmet dependencies.
- Make features smaller in
.ralph/prd.json - Use
estimated_complexityto keep features small - Emphasize "ONE feature per iteration" in prompt
- Automatic verification is now enabled by default
- Ensure browser automation tools are available
- Add explicit testing steps to each feature
- Automatic rollback will revert the commit
- Check rollback logs for failure details
- Feature will need to be reworked
- Set
"blocked_reason"in PRD with explanation - Agent will skip blocked features
- Document blocker in progress.txt
- Check
depends_onarrays in PRD - Ensure all dependencies have
"passes": true - Agent automatically skips features with unmet dependencies
- Add
type: "refactor"features to.ralph/prd.json - Run linters after each iteration
- Review and refactor periodically
- Ensure
.ralph/progress.txthas detailed notes - Write descriptive git commits
- Include "next steps" in progress log
- The
.ralph/directory should be in.gitignore - Initializer agent creates this automatically
- For existing projects, add manually:
echo ".ralph/" >> .gitignore
Web Apps: Include browser automation (Playwright/Puppeteer) APIs: Focus on endpoint testing with curl/supertest Libraries: Emphasize unit tests and examples CLIs: Test with actual command execution
# Continuous mode with custom iteration limit
MAX_ITERATIONS=50 RUN_MODE=continuous ./ralph.sh
# Human-in-the-loop always runs just 1 iteration
./ralph.shRalph includes built-in safety features to prevent accidental commits to important branches and unauthorized pushes:
# Work on a feature branch (required - protected branches blocked by default)
git checkout -b feature/my-feature
./ralph.sh
# Override protected branches (not recommended)
PROTECTED_BRANCHES="" ./ralph.sh
# Change which branches are protected (default: main,master)
PROTECTED_BRANCHES="main,master,production" ./ralph.sh
# Enable git push operations (disabled by default for safety)
ALLOW_GIT_PUSH=true ./ralph.shSafety Features:
- Protected Branches: By default, Ralph will exit with an error if you try to run it on
mainormasterbranches - No Push by Default: Git push operations are blocked unless
ALLOW_GIT_PUSH=trueis set - Feature Branch Workflow: Encourages working on feature branches to keep main clean
- Helpful Error Messages: Provides clear instructions when safety checks fail
Best Practice: Always work on a feature branch:
git checkout -b feature/add-authentication
./ralph.shRalph can automatically create feature branches when you run it on a protected branch (like main or master). This eliminates the manual step of creating branches!
How it works:
- Run Ralph on a protected branch (e.g.,
main) - Ralph inspects your PRD to find the next feature to implement
- Ralph auto-generates a branch name based on the feature type and description
- Ralph creates and switches to the new branch
- Ralph proceeds with the iteration
Branch naming convention:
feature/{id}-{slug}- for type: "feature"bugfix/{id}-{slug}- for type: "bug"refactor/{id}-{slug}- for type: "refactor"test/{id}-{slug}- for type: "test"
Example: Feature 000a with description "Auto-create feature branches..." becomes:
feature/000a-auto-create-feature-branches
Usage:
# Auto-create branch (enabled by default)
cd /path/to/your/project
git checkout main
./ralph.sh
# Ralph detects protected branch, inspects PRD, creates feature/000a-auto-create-feature-branches
# Specify custom branch name
./ralph.sh --branch-name my-custom-branch
# Disable auto-creation (require manual branch creation)
AUTO_CREATE_BRANCH=false ./ralph.sh
# Help
./ralph.sh --helpConfiguration:
# Enable/disable auto-branch creation (default: true)
AUTO_CREATE_BRANCH=true ./ralph.sh
# Custom branch name via parameter
./ralph.sh --branch-name feature/my-custom-feature
# Works with other options
RUN_MODE=continuous AUTO_CREATE_BRANCH=true ./ralph.shBenefits:
- β No more manually creating feature branches
- β Consistent branch naming across your project
- β Branch names match the feature being implemented
- β Safe to run Ralph on main - it automatically moves to a feature branch
- β Conventional branch prefixes (feature/, bugfix/, etc.) for better organization
# Human-in-the-loop with manual agent control
RUN_MODE=once AI_AGENT_MODE=manual ./ralph.sh
# Continuous with custom files
RUN_MODE=continuous PRD_FILE=.ralph/features.json ./ralph.sh
# Feature branch with push enabled
git checkout -b feature/my-feature
ALLOW_GIT_PUSH=true ./ralph.sh
# All options combined
RUN_MODE=continuous AI_AGENT_MODE=claude MAX_ITERATIONS=50 ./ralph.shA well-running Ralph loop shows:
- β Consistent commit history (1 feature = 1 commit)
- β
Decreasing
"passes": falsecount in.ralph/prd.json - β
Detailed progress notes in
.ralph/progress.txtafter each iteration - β Tests passing continuously (automatic verification)
- β Clean, working code at all times
- β
.ralph/directory properly gitignored - β Features with dependencies completed in order
- β
Accurate
iterations_takentracking - β Minimal blocked features
- EXAMPLE_OUTPUT.txt - See a real Ralph iteration from start to finish (feature selection, implementation, testing, commit)
- Matt Pocock: Ship working code while you sleep (YouTube) - Great video introduction to the Ralph technique
- Dex & Geoffrey Huntley: Ralph Wiggum Methodology Deep Dive (YouTube) - Technical comparison of bash-loop vs plugin approaches, context engineering, and security considerations
- Anthropic: Effective harnesses for long-running agents
- Geoffrey Huntley: Ralph Wiggum as a "software engineer"
- Claude Agent SDK Documentation
This is a living document. Improvements welcome:
- Better prompt engineering
- Additional templates
- Integration examples
- Project type variations
Feel free to use, modify, and distribute. Attribution appreciated.
Ready to build something? Start with INITIALIZER_PROMPT.md or AGENT_PROMPT.md!