Ralph Practical Guide
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:
| Dependency | Description |
|---|---|
| AI Coding Tool | Claude Code (npm install -g @anthropic-ai/claude-code) or Amp CLI |
| jq | JSON processing tool (macOS: brew install jq) |
| Git | Project must be a Git repository |
# Check dependencies
claude --version # Claude Code CLI
jq --version # JSON processing
git --version # GitInstallation & Configuration
snarktank/ralph offers multiple installation methods. Choose based on your use case.
Option 1: Install Directly in Claude Code (Recommended)
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/ralphClaude 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-marketplaceAfter 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.shAfter 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 CodeEach iteration, ralph.sh performs these steps:
- Creates a feature branch (from
branchNamein prd.json) - Selects the highest-priority incomplete story (
passes: false) - Spawns a brand new AI instance to implement this story
- Runs quality checks (type checking, tests)
- Checks pass → git commit; checks fail → left for next iteration
- Updates prd.json, marking the story as
passes: true - Appends learnings to progress.txt
- 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 50prd.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:
| Field | Description |
|---|---|
projectName | Project name, used for logging and branch naming |
branchName | Git branch name — Ralph creates it automatically |
id | Unique story ID, recommend US-001 format |
title | Short title |
description | Detailed description — the more specific, the better |
acceptanceCriteria | List of acceptance criteria — this is the most critical field |
priority | Priority number — lower executes first |
passes | Whether completed — Ralph updates this automatically |
dependsOn | List of dependent story IDs |
notes | Additional 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 translatedThe 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 translationsWriting 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 EnglishThe 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.jsonWriting 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 20The 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.txtAutomatic 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 passQuality Gate Layers
| Layer | Tool | Issues Caught |
|---|---|---|
| Immediate feedback | TypeScript compiler | Type errors, syntax errors |
| Functional verification | Unit tests | Logic errors, edge cases |
| Integration verification | Build command | Dependency issues, configuration errors |
| Runtime verification | dev-browser skill | UI 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:
- Check progress.txt to see what's blocking
- Fix the issue manually and re-run
- Adjust story granularity (it might be too large)
- 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 language4. 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 storyCase 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 storyEach 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:
-
File as source of truth: The
prd.jsontracked which stories passed (passes: true/false). Theprogress.txtaccumulated learnings across iterations — e.g., "Typecheck command ispnpm types:check, notpnpm typecheck" -
Automated quality gate: After each translation,
pnpm types:checkran to verify the MDX files compiled correctly. If typecheck failed, the issue was fixed before committing. -
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. -
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
| Learning | Details |
|---|---|
| Accumulated knowledge matters | Early stories discovered patterns (QuoteCard defaultLang, link prefixing rules) that made later stories faster |
| Typecheck as feedback loop | Caught issues like missing imports or malformed MDX before they could compound |
| Parallelization scales | 6 translation agents running simultaneously completed in roughly the same time as 1 |
| PRD granularity is critical | Each story was scoped to 1-2 files — small enough to complete reliably, large enough to be meaningful |
| Progress log prevents repeat mistakes | The 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:
| Resource | Link | Description |
|---|---|---|
| snarktank/ralph | snarktank/ralph | Used in this article, most feature-complete |
| ralph-orchestrator | mikeyobrien/ralph-orchestrator | By Mickey O'Brien, with more customization options |
| ralph-loop-agent | vercel-labs/ralph-loop-agent | Vercel's implementation based on the AI SDK |
| ralphy | michaelshimeles/ralphy | Michael 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.
| Resource | Link | Description |
|---|---|---|
| GSD (Get Stuff Done) | glittercowboy/get-shit-done | A 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.
Recommended Resources
Official Sources:
| Resource | Link | Description |
|---|---|---|
| Geoffrey Huntley's Blog | ghuntley.com/ralph | The inventor's original article |
| how-to-ralph-wiggum | ghuntley/how-to-ralph-wiggum | Official usage guide |
Video Tutorials:
| Resource | Link | Description |
|---|---|---|
| Ralph Wiggum Deep Discussion | Why Claude Code's implementation isn't it | Geoffrey Huntley explains the problems with the official implementation |
| Using Ralph Correctly | You're Using Ralph Wiggum Loops WRONG | Roman (Mentat)'s usage walkthrough |
| We need to talk about Ralph | We need to talk about Ralph | Theo'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?
- Check progress.txt for the failure reason
- Add more context in notes
- Split the story (it may be too large)
- 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 ResultsThe 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
- Ralph Wiggum Deep Dive — Revisit Ralph's core principles
- GSD Deep Dive — A complete context engineering system built on Ralph's foundations
- What Are Claude Skills — Ralph's PRD skill is a Claude Skill
- Speckit Practical Guide — Another structured AI programming workflow