Skip to main content
Ralph Wiggum

Ralph Practical Guide

AI-assisted

Complete operational manual for snarktank/ralph — from installation to real-world use, covering PRD writing, loop execution, quality gates, and lessons learned

Introduction

In the previous article, we explored Ralph's core principles — infinite loop + fresh context each time + files as the source of truth. These three pillars sound simple, but there are quite a few details to work through between understanding the concept and actually getting it running.

In this article, we'll get hands-on. You'll learn how to use snarktank/ralph to complete the full workflow from installation to execution. snarktank/ralph is one of the most mature Ralph implementations in the community (10k+ stars), supporting both Claude Code and Amp, with a complete toolchain for PRD generation, JSON conversion, and automated execution.

Prerequisites

Before getting started, make sure your environment meets these requirements:

DependencyDescription
AI Coding ToolClaude Code (npm install -g @anthropic-ai/claude-code) or Amp CLI
jqJSON processing tool (macOS: brew install jq)
GitProject must be a Git repository
# Check dependencies
claude --version   # Claude Code CLI
jq --version       # JSON processing
git --version      # Git

Installation & Configuration

snarktank/ralph offers multiple installation methods. Choose based on your use case.

The simplest approach — paste the GitHub link in a Claude Code conversation and let Claude handle the installation automatically:

Install this skill for me: https://github.com/snarktank/ralph

Claude Code will automatically clone the repository and copy the skill files to the correct location. Once installed, you can use the /prd and /ralph commands.

Option 2: Claude Code Marketplace

Install via Marketplace commands:

# Add and install the plugin
/plugin marketplace add snarktank/ralph
/plugin install ralph-skills@ralph-marketplace

After installation, you'll have access to /prd (generate PRD) and /ralph (convert to JSON) skills.

Option 3: Manual Skill Installation (Claude Code / Amp)

Manually copy the skill files to the corresponding tool's global config directory:

# Clone the repository first
git clone https://github.com/snarktank/ralph.git /tmp/ralph

# For Claude Code users
cp -r /tmp/ralph/skills/prd ~/.claude/skills/
cp -r /tmp/ralph/skills/ralph ~/.claude/skills/

# For Amp users
cp -r /tmp/ralph/skills/prd ~/.config/amp/skills/
cp -r /tmp/ralph/skills/ralph ~/.config/amp/skills/

After installation, you can use the /prd and /ralph commands.

Option 4: Project-Level Installation

Copy Ralph scripts directly into your project — best for teams that need to share or customize scripts:

# Clone the Ralph repository
git clone https://github.com/snarktank/ralph.git /tmp/ralph

# Copy core files to your project
mkdir -p scripts/ralph
cp /tmp/ralph/ralph.sh scripts/ralph/
cp /tmp/ralph/CLAUDE.md scripts/ralph/   # For Claude Code users
# OR
cp /tmp/ralph/prompt.md scripts/ralph/   # For Amp users

# Grant execution permission
chmod +x scripts/ralph/ralph.sh

After installation, your project will have this structure:

your-project/
├── scripts/ralph/
│   ├── ralph.sh        # Core loop script
│   └── CLAUDE.md       # Prompt template for Claude Code
├── tasks/              # PRD file directory (created automatically during execution)
│   └── prd.json        # Your task definitions
└── ...

Recommendation: Option 1 is the easiest — just give Claude Code the GitHub link. For manual control over the installation process, choose Option 2 (Marketplace commands) or Option 3 (manual copy). Use Option 4 when you need team sharing or script customization.


Core File Structure

Ralph's memory relies entirely on the file system. Understanding each file's role is essential to using Ralph effectively.

ralph.sh — The Loop Engine

This is Ralph's core: a bash script that repeatedly spawns new AI instances.

# Basic usage
./scripts/ralph/ralph.sh [max_iterations]        # Default: Amp
./scripts/ralph/ralph.sh --tool claude [iterations]  # Use Claude Code

Each iteration, ralph.sh performs these steps:

  1. Creates a feature branch (from branchName in prd.json)
  2. Selects the highest-priority incomplete story (passes: false)
  3. Spawns a brand new AI instance to implement this story
  4. Runs quality checks (type checking, tests)
  5. Checks pass → git commit; checks fail → left for next iteration
  6. Updates prd.json, marking the story as passes: true
  7. Appends learnings to progress.txt
  8. Repeats until all stories are complete or iteration limit is reached

Default iteration limit is 10. Adjust based on project complexity:

# Simple project
./scripts/ralph/ralph.sh --tool claude 10

# Complex project
./scripts/ralph/ralph.sh --tool claude 50

prd.json — Task Definitions

This is Ralph's "brain" — all tasks are defined here. It's a flat JSON file:

{
  "projectName": "Blog i18n Translation",
  "branchName": "ralph/i18n-translation",
  "userStories": [
    {
      "id": "US-001",
      "title": "Translate homepage metadata",
      "description": "Create content/docs/meta.en.json with English translations for all navigation items",
      "acceptanceCriteria": [
        "meta.en.json file exists with valid JSON format",
        "All navigation titles are translated to English",
        "pnpm types:check passes"
      ],
      "priority": 1,
      "passes": false,
      "dependsOn": [],
      "notes": "Reference the existing meta.json structure"
    },
    {
      "id": "US-002",
      "title": "Translate blog post hello-world",
      "description": "Create content/blog/hello-world.en.mdx, translated from Chinese to English",
      "acceptanceCriteria": [
        "hello-world.en.mdx file exists",
        "All QuoteCard components have defaultLang='en'",
        "Internal links use /en/ prefix",
        "Code blocks remain untranslated",
        "pnpm types:check passes"
      ],
      "priority": 2,
      "passes": false,
      "dependsOn": ["US-001"],
      "notes": "Preserve MDX component props format"
    }
  ]
}

Field reference:

FieldDescription
projectNameProject name, used for logging and branch naming
branchNameGit branch name — Ralph creates it automatically
idUnique story ID, recommend US-001 format
titleShort title
descriptionDetailed description — the more specific, the better
acceptanceCriteriaList of acceptance criteria — this is the most critical field
priorityPriority number — lower executes first
passesWhether completed — Ralph updates this automatically
dependsOnList of dependent story IDs
notesAdditional hints and context

progress.txt — Learnings Log

This is Ralph's "long-term memory." After each iteration, the AI appends what it learned:

=== Iteration 1 (US-001) ===
- Discovered: typecheck command is `pnpm types:check`, not `pnpm typecheck`
- Discovered: meta.en.json needs to mirror exact structure of meta.json
- Pattern: fumadocs i18n uses `.en.` suffix convention

=== Iteration 2 (US-002) ===
- Discovered: QuoteCard requires both `quote` and `quoteZh` props
- Gotcha: internal links must use /en/ prefix for English pages
- Pattern: code blocks should never be translated

The next iteration's fresh Claude instance reads this file, immediately gaining all previous experience. This is why Ralph gets smoother over time — knowledge accumulates across iterations while context stays clean.

AGENTS.md — Persistent Knowledge Base

Beyond progress.txt, Ralph also updates AGENTS.md (or CLAUDE.md) files in the project. Both Claude Code and Amp automatically read these files on startup.

Unlike progress.txt, AGENTS.md records stable, cross-project knowledge:

# AGENTS.md

## Codebase Conventions
- Use fumadocs for documentation framework
- MDX files use custom components: QuoteCard, BlogImage, GlossaryCard
- i18n files use `.en.mdx` suffix

## Gotchas
- Always run `pnpm types:check` after modifying MDX files
- QuoteCard: set `defaultLang='en'` in English translations

Writing a PRD

The quality of your PRD (Product Requirements Document) directly determines how well Ralph executes. Write it well, and Ralph sails through. Write it poorly, and Ralph will repeatedly fail on the same story.

Using Skills to Generate a PRD

If you installed snarktank/ralph's skills, you can generate a PRD interactively:

# In Claude Code or Amp
/prd I want to add i18n support to the blog, translating all Chinese content to English

The AI will ask you clarifying questions (which files are involved, tech stack constraints, quality standards, etc.), then generate a structured PRD document.

After generation, use the /ralph command to convert the PRD to prd.json format:

/ralph    # Convert PRD to prd.json

Writing PRD Manually

You can also write prd.json directly. Here are the key design principles.

Principle 1: Right-size your stories

Each story should be small enough to complete in one iteration, yet large enough to deliver independent value.

// ❌ Too large: can't finish in one iteration
{
  "id": "US-001",
  "title": "Build complete user authentication system",
  "description": "Implement registration, login, forgot password, OAuth, permission management..."
}

// ❌ Too small: no independent value
{
  "id": "US-001",
  "title": "Create email field on User table",
  "description": "Add email field to User model"
}

// ✅ Just right: completable in one iteration, delivers independent value
{
  "id": "US-001",
  "title": "Implement email/password login",
  "description": "Create login API and login page with email/password authentication",
  "acceptanceCriteria": [
    "POST /api/auth/login accepts email + password",
    "Returns JWT token",
    "Login page form submits successfully",
    "All tests pass"
  ]
}

Rule of thumb: A story involves 1-3 file modifications and has 3-5 acceptance criteria.

Principle 2: Acceptance criteria must be automatically verifiable

Ralph needs to determine whether a story is complete, so acceptance criteria must be objectively assessable:

// ❌ Vague criteria
"acceptanceCriteria": [
  "Code quality is good",
  "Performance is decent",
  "User experience is smooth"
]

// ✅ Verifiable criteria
"acceptanceCriteria": [
  "pnpm types:check passes",
  "pnpm test passes",
  "API response time < 200ms",
  "File src/auth/login.ts exists and exports loginHandler function"
]

Principle 3: Use dependsOn to control ordering

Some stories have dependencies. The dependsOn field ensures Ralph executes in the correct order:

{
  "userStories": [
    {
      "id": "US-001",
      "title": "Create database schema",
      "dependsOn": []
    },
    {
      "id": "US-002",
      "title": "Implement user registration API",
      "dependsOn": ["US-001"]
    },
    {
      "id": "US-003",
      "title": "Implement login page",
      "dependsOn": ["US-002"]
    }
  ]
}

Principle 4: Provide context in notes

The notes field gives the AI extra hints. Write things here that you know but the AI might not:

{
  "notes": "Project uses fumadocs framework, i18n files follow .en.mdx suffix naming. Reference content/docs/notes/speckit/concept.en.mdx for translation style."
}

Executing the Ralph Loop

With the PRD ready, it's time to run the loop.

Starting Execution

# Using Claude Code, default 10 iterations
./scripts/ralph/ralph.sh --tool claude

# Specify iteration count
./scripts/ralph/ralph.sh --tool claude 30

# Using Amp (default)
./scripts/ralph/ralph.sh 20

The Execution Process

After starting, you'll see output like this:

=== Ralph Loop - Iteration 1 ===
Branch: ralph/i18n-translation
Selected story: US-001 - Translate homepage metadata
Spawning fresh Claude instance...

[Claude Code executing...]

Quality check: pnpm types:check ... PASSED
Committing: feat: [US-001] - Translate homepage metadata
Updating prd.json: US-001 passes: true
Appending to progress.txt

=== Ralph Loop - Iteration 2 ===
Selected story: US-002 - Translate blog post hello-world
Spawning fresh Claude instance...

Each iteration is a brand new Claude instance. It knows what to do by reading prd.json, and it knows what was learned previously by reading progress.txt.

Completion Signal

When all stories are marked passes: true, Ralph outputs a completion signal and exits:

All stories completed!
<promise>COMPLETE</promise>

Monitoring & Debugging

While Ralph is running, you can check progress with these commands:

# View completion status for each story
cat tasks/prd.json | jq '.userStories[] | {id, title, passes}'

# View learnings log
cat progress.txt

# Check recent git commits
git log --oneline -10

# Watch Ralph's output in real-time
tail -f progress.txt

Automatic Archiving

When you start a different feature with a new branchName, Ralph automatically archives the previous run's files to archive/YYYY-MM-DD-feature-name/, keeping the working directory clean.


Feedback Loops & Quality Gates

Ralph's "self-correction" ability depends entirely on the quality of the feedback loop. Without a feedback loop, Ralph is just a blind looping script — it will keep producing code but has no way to tell if the code is correct.

Configuring Quality Checks

Define your quality check commands in CLAUDE.md (or prompt.md):

## Quality Commands

After implementing each story, run these checks IN ORDER:

1. `pnpm types:check` — TypeScript type checking
2. `pnpm test` — Unit tests
3. `pnpm build` — Full build verification

If any check fails:
- DO NOT commit
- Fix the issue
- Re-run all checks
- Only commit when all checks pass

Quality Gate Layers

LayerToolIssues Caught
Immediate feedbackTypeScript compilerType errors, syntax errors
Functional verificationUnit testsLogic errors, edge cases
Integration verificationBuild commandDependency issues, configuration errors
Runtime verificationdev-browser skillUI rendering issues (frontend projects)

For frontend stories, Ralph recommends adding this acceptance criterion: "Verify in browser using dev-browser skill" — letting the AI actually open a browser to confirm the page renders correctly.

When Quality Checks Fail

If a story's quality checks fail repeatedly, Ralph won't retry the same story indefinitely. After reaching the iteration limit, it stops and leaves the current state. You can:

  1. Check progress.txt to see what's blocking
  2. Fix the issue manually and re-run
  3. Adjust story granularity (it might be too large)
  4. Add more context in the notes field

Prompt Customization

Ralph's prompt template (CLAUDE.md or prompt.md) is your primary means of controlling AI behavior. After installation, you should customize it for your project.

Key Customizations

1. Project-specific quality commands

## Project-Specific Commands
- Typecheck: `pnpm types:check` (not `tsc` or `pnpm typecheck`)
- Test: `pnpm vitest run`
- Build: `pnpm build`
- Lint: `pnpm lint`

2. Code style constraints

## Code Conventions
- Use TypeScript strict mode
- Prefer named exports over default exports
- Use fumadocs components for MDX content
- Follow existing file naming patterns (kebab-case)

3. Known gotchas

## Known Gotchas
- MDX files: always import components at the top
- i18n: English files use `.en.mdx` suffix
- Links: English pages must use `/en/` prefix
- QuoteCard: set `defaultLang` to match the file language

4. Handling stuck situations

## When Stuck
If you cannot complete a story after 3 attempts within the same iteration:
1. Document what's blocking in progress.txt
2. Move to the next story if possible
3. Do NOT modify files unrelated to the current story

Case Study: Blog i18n Translation with Ralph

To illustrate how Ralph works in practice, here's a real-world example: translating this entire blog from Chinese to English using a Ralph-style autonomous agent.

The Setup

The project required translating 22+ content files (blog posts, documentation, navigation metadata) from Chinese to English for a fumadocs-based Next.js blog with i18n support. The task was defined in a prd.json file with 16 user stories, each with clear acceptance criteria:

scripts/ralph/
├── prd.json          # 16 user stories with acceptance criteria
└── progress.txt      # Learnings log, updated after each story

Each user story followed a consistent pattern:

  • Clear deliverables: "Create content/blog/xxx.en.mdx"
  • Verifiable criteria: "Typecheck passes", "Internal links use /en/ prefix"
  • Technical constraints: "Keep code blocks untranslated", "Set defaultLang='en' on QuoteCard"

The Execution Pattern

The agent followed the Ralph methodology's core principles:

  1. File as source of truth: The prd.json tracked which stories passed (passes: true/false). The progress.txt accumulated learnings across iterations — e.g., "Typecheck command is pnpm types:check, not pnpm typecheck"

  2. Automated quality gate: After each translation, pnpm types:check ran to verify the MDX files compiled correctly. If typecheck failed, the issue was fixed before committing.

  3. Incremental progress: Each story was committed independently with a descriptive message (feat: [US-003] - Translate blog/claude-code-quality-control.mdx), enabling easy rollback if needed.

  4. Parallel execution: For longer articles, multiple subagents translated files simultaneously — e.g., US-010 (claude-skills concept + practice), US-011 (speckit concept + practice), and US-012 (claude-architecture + claude-subagent) all ran in parallel.

Key Learnings

LearningDetails
Accumulated knowledge mattersEarly stories discovered patterns (QuoteCard defaultLang, link prefixing rules) that made later stories faster
Typecheck as feedback loopCaught issues like missing imports or malformed MDX before they could compound
Parallelization scales6 translation agents running simultaneously completed in roughly the same time as 1
PRD granularity is criticalEach story was scoped to 1-2 files — small enough to complete reliably, large enough to be meaningful
Progress log prevents repeat mistakesThe progress.txt "Codebase Patterns" section became a knowledge base that prevented rediscovering the same issues

Results

16 user stories completed across a single session: 8 meta.en.json navigation files created, 3 blog posts translated, 12 documentation pages translated, full site build verified. Each translation maintained consistent quality because the acceptance criteria were explicit and the feedback loop (typecheck) caught issues immediately.

This project demonstrates Ralph's Full Implementation Mode in action — a well-defined task with clear success criteria, automated verification, and incremental delivery through the file system.


Community Implementations & Alternatives

snarktank/ralph isn't the only choice. Depending on your needs, these implementations each have their strengths:

ResourceLinkDescription
snarktank/ralphsnarktank/ralphUsed in this article, most feature-complete
ralph-orchestratormikeyobrien/ralph-orchestratorBy Mickey O'Brien, with more customization options
ralph-loop-agentvercel-labs/ralph-loop-agentVercel's implementation based on the AI SDK
ralphymichaelshimeles/ralphyMichael Shimeles' lightweight implementation

Alternative: GSD

GSD is not strictly a "community implementation" of Ralph — it's an alternative approach. It applies Ralph's core principles (context management, atomic tasks) but provides a more complete workflow: discuss → plan → execute → verify.

ResourceLinkDescription
GSD (Get Stuff Done)glittercowboy/get-shit-doneA complete framework from idea to PRD to execution

If you find Ralph too "raw" and need more process support, GSD might be a better fit. See GSD Deep Dive for details.


Official Sources:

ResourceLinkDescription
Geoffrey Huntley's Blogghuntley.com/ralphThe inventor's original article
how-to-ralph-wiggumghuntley/how-to-ralph-wiggumOfficial usage guide

Video Tutorials:

ResourceLinkDescription
Ralph Wiggum Deep DiscussionWhy Claude Code's implementation isn't itGeoffrey Huntley explains the problems with the official implementation
Using Ralph CorrectlyYou're Using Ralph Wiggum Loops WRONGRoman (Mentat)'s usage walkthrough
We need to talk about RalphWe need to talk about RalphTheo's analysis of the controversy

Best Practices & FAQ

Cost Control

Ralph's automated execution means API costs are continuously incurred. A few control measures:

  • Always set max_iterations: This is the most basic safety net
  • Keep story granularity reasonable: Stories that are too large consume multiple iterations; stories that are too granular increase startup overhead
  • Test small first: For new projects, do a trial run with 3-5 iterations to confirm your prompt and quality gates are working before scaling up

Common Pitfalls

Pitfall 1: Stories too large

Symptoms: A story fails repeatedly, iteration count depletes quickly.

Solution: Split into 2-3 smaller stories. "Build complete auth system" becomes "Implement login API" + "Create login page" + "Add JWT middleware."

Pitfall 2: No feedback loop

Symptoms: Ralph claims stories are complete, but the actual code has issues.

Solution: Add executable check commands to acceptance criteria. "Code is written" is not an acceptance criterion — "pnpm test all passes" is.

Pitfall 3: progress.txt not being utilized

Symptoms: The same error recurs across different iterations.

Solution: Verify your prompt template explicitly instructs "Read progress.txt and follow the learnings within." If the AI isn't appending learnings automatically, add "After each story, append learnings to progress.txt" to your prompt.

Pitfall 4: Incorrect dependency ordering

Symptoms: A story depends on code that doesn't exist yet, causing implementation failure.

Solution: Set the dependsOn field correctly. Ensure infrastructure stories come first.

FAQ

Q: What's the difference between Ralph and the official plugin?

The core difference: snarktank/ralph spawns a new process each iteration (truly fresh context), while the official plugin loops within the same session (context keeps accumulating). See the analysis in the previous article for details.

Q: Can I manually modify prd.json mid-execution?

Yes. Ralph re-reads prd.json at the start of each iteration. You can modify story descriptions, add new stories, or manually mark a story as passes: true (to skip it) between iterations.

Q: What if Ralph gets stuck on a story that keeps failing?

  1. Check progress.txt for the failure reason
  2. Add more context in notes
  3. Split the story (it may be too large)
  4. Fix the blocking issue manually and re-run

Q: Can I do other things while Ralph runs?

Yes. Ralph is designed for "Human on the Loop" — you don't need to watch it. In AFK mode, start it before leaving work and check results the next day. Just don't modify files that Ralph is actively working on.

Q: How do I control costs?

Three approaches: set a reasonable max_iterations, keep story granularity appropriate (reducing wasted iterations), and do a small trial run first to confirm the workflow is correct. Generally, a project with 10-20 stories falls within $50-100 in API costs.


Summary

Ralph's workflow can be distilled into five steps:

Install → Write PRD → Configure Quality Gates → Run Loop → Review Results

The core philosophy never changes: let files be the source of truth, let every iteration start fresh, and let quality gates do the gatekeeping for you.

Now, go back to your project, prepare your prd.json, run ./scripts/ralph/ralph.sh --tool claude, and go grab a coffee.

Further Reading

Comments

Table of Contents