The Ralph Loop
The Ralph Loop has completely changed how I write software. For over a decade, my workflow for implementing a feature looked like this:
- Step 1: write a tech spec (maybe informal; maybe just a Markdown file in Vimwiki).
- Step 2: add a few TODO tasks (obvious, low-hanging fruit that I should pick up next).
# Implement 2FA with SMS
- links to third-party SMS provider |
- links to Figma designs |<- my understanding on day 1
- functional requirement 1 |
- functional requirement 2 |
# TODO
- [ ] Add a `user_sms` table + migration |
- [ ] Add a `POST /v1/sms/pin` API |<- low-hanging fruit
- Step 3: implement the TODO items.
- Step 4: think about what to do next.
Go back to step 3 and repeat until the project is complete.
The way I use the Ralph Loop now isn’t too different from that approach; the key difference is that the TODOs are done by LLMs (GPT-5.2 (xhigh) or Opus 4.5 (max)).
I use OpenCode with a script to automate most of step 3 (implementing the TODO items).
ralph.ts # it's somewhere on my PATH
ralph.md # the system prompt for the Ralph Loop
# <current project files>
.opencode/
├── opencode.json # OpenCode permission/settings
├── log-sms.md # append-only log for the LLM
└── prd-sms.md # the PRD file
The setup is dead simple. I run ralph.ts <iterations> .opencode/prd-<name>.md. The script takes the ralph.md system prompt, inlines the paths to .opencode/prd-<name>.md and .opencode/log-<name>.md, and runs a new OpenCode session.
It’s basically a for loop. The system prompt (ralph.md) instructs the LLM to mark the TODO item as complete, append progress to .opencode/log-<name>.md, and commit the changes.
Here is the full prompt ralph.md:
# Ralph Agent Instructions
You are an autonomous coding agent responsible for executing tasks within a software project.
## Your Task Pipeline
1. **Contextual Review:**
* Read the PRD at `RALPH_PRD_PATH`.
* Read the progress log at `RALPH_LOG_PATH`.
2. **Incremental Planning:**
* Decide on a single, granular step to move the project closer to the full PRD implementation.
* Steps need not be sequential, pick the one that feels right as the next step.
3. **Execution:**
* Implement that single step -- this is where you will spend most of your time.
4. **Validation:**
* Do everything that is available to verify that the changes are correct.
5. **Version Control:**
* Commit code changes with the message: `feat: [Item Title]`.
* *Note: Skip `.opencode/` folder changes and any existing untracked files.*
## Progress Log Format
*Append-only. Information density is key.*
\`\`\`md
[short commit hash]
- informative (not prescriptive) notes to future self;
such as learnings, patterns, gotchas, and/or useful snippets.
\`\`\`
> **Note:** The "Learnings" section is vital for helping future iterations pick up the next steps effectively.
---
## After Completing the Step
* Mark the step as complete in the `# Suggested Next Steps` section of `RALPH_PRD_PATH`.
* If there aren't enough steps left, add a new step to find more steps.
* The goal is to include a dedicated step where you act as a slow, deliberate, and analytical thinker: an experienced architect and a rigorous QA specialist, to identify future steps.
* Improve existing steps, remove those that no longer apply (if any), and sort them by readiness to be picked up.
## Core Principles
* **Atomic Progress:** Work on **ONE** step at a time and commit frequently.
* **Excellence:** Strive for high-quality implementation in every iteration.
The .opencode/prd-sms.md might look something like this:
We are building SMS authentication with provider XYZ.
You can read the docs at http://xyz.com/docs/sms/api
Use the Figma MCP to inspect these node IDs: 110-5501 110-5729 290-8616
# Suggested Next Steps
- [ ] Add a `user_sms` table + migration
- [ ] Add a `POST /v1/sms/pin` API
- [ ] Study what needs to be done next and add a few more suggested steps.
And the ralph.ts script is the glue that runs the loop, plus a few extra niceties like opening the OpenCode web UI so I can inspect progress more easily.
Here is the full ralph.ts click to download.
I hope you find this useful. This has significantly changed how I write code in 2026.
The PRD becomes of utmost importance: I spend a lot of time manually editing it to make sure it’s solid. I gave a short example above, but usually instead of instructions like “read this URL” or “use the Figma MCP”, I do those ahead of time and put the materials somewhere on the filesystem so they’re easily accessible to the LLM. We want to avoid extra cognitive overhead for the LLM (this is called context rot).
Of course, not everything is sunshine and rainbows after the loops are done. I find myself adding a few more TODO items just to clean the slop; or, at worst, manually editing the code. I’d say slop cleanup takes about 60% of my time, but it’s still worth it because I’m 2x to 3x faster and much less mentally exhausted at the end of the day.