← jordandalton.com
June 6, 2026

Ralph Loop Junkie: Ship Apps With Autonomous Coding Agents

Ralph Loop Junkie is my open-source app for running coding agents in Ralph loops. Here's what a Ralph loop is, why it works, and how I ship code overnight.

Just one more iteration.

Most of the code I've shipped lately wasn't written while I was sitting at the keyboard. Agents wrote it, running in loops overnight, while I was at lunch, while I was doing pretty much anything other than babysitting a terminal. The technique behind this is called a Ralph loop, and today I'm open-sourcing the desktop app I built to manage them: Ralph Loop Junkie.

Maybe you've been watching the agentic-coding space and wondering how people get coding agents to do real work for hours at a stretch instead of one-off completions. If so, this post is for you. I'll cover what a Ralph loop is, why it's caught on with engineers building autonomous systems, and what I built on top of it.

What's a Ralph loop?

The name comes from Geoffrey Huntley, who popularized the pattern. You take a coding agent and run it in a continuous loop. Each iteration gets a fresh context and reads a small, durable set of plan files, and the loop keeps going until the work is genuinely finished.

The "fresh context" part is counterintuitive, so it's worth slowing down on. Most people's instinct with an agent is to keep one long conversation going, building up context over time so the model "remembers" everything. But long-running agent sessions degrade. The context window fills up with stale reasoning, half-abandoned approaches, and noise, and the agent starts losing the plot, contradicting earlier decisions, or burning tokens re-reading its own confusion.

A Ralph loop does the opposite. Rather than one ever-growing session, it re-spawns a brand-new agent every iteration, each one starting clean and reading the same small set of files:

<loop-id>/
├── plans/
│   ├── PRD.md           # what the loop should accomplish
│   ├── PROMPT.md        # instructions for the agent
│   ├── tasks.json       # the task list (status drives completion)
│   └── ralph-state.md   # the loop's working memory across iterations
└── scripts/ralph/
    └── ralph.sh         # the loop entrypoint

The state doesn't live in the model's context. It lives on disk, in files the agent reads and writes. Each iteration, ralph.sh does roughly this:

  1. Invoke an agent CLI against the plan files. (The default calls claude --print, but ralph.sh is just a shell script, so you can swap in Codex, an OpenRouter-backed CLI, or whatever non-interactive agent you prefer.)
  2. Have the agent pick the next unfinished task, do the work, and mark it done in tasks.json.
  3. Run a verification command. It's true by default, but you swap in your actual test suite.
  4. Re-read tasks.json and exit only when every task is done and verification passes.

That last step matters most to me. The loop does not trust a self-reported "I'm finished." Agents are notoriously eager to declare victory, so the loop checks the actual task statuses on disk and the result of the verification command. The agent doesn't get to vote on whether it's done; the data does.

Why this approach has caught on

I won't pretend every engineer alive uses Ralph loops. The autonomous-agent world is opinionated and this approach has its critics. But among people seriously building agents that run unattended, the pattern has earned real traction, and the reasons are concrete:

Fresh context beats accumulated context. Starting clean each iteration sidesteps the slow degradation that kills long sessions. The agent always works from a tidy, deliberate prompt plus durable state, rather than a sprawling transcript of its own second-guessing.

Files are the memory, and files are reviewable. Because state lives in tasks.json, ralph-state.md, and friends, you can open them, read them, and edit them. The loop's "thinking" is inspectable in a way an opaque context window never is. When something goes sideways, you can see exactly what the loop believed and fix it.

Completion is defined by verifiable conditions, not vibes. The loop terminates on real signals: all tasks marked done, tests passing. That's the gap between an agent that says it shipped and one that actually did.

It's model-agnostic and dead simple. It's a shell script. There's no framework lock-in and no orchestration platform to learn. If a better agent CLI comes out next month, you change one line.

Put those together and you get a loop that can run for hours and still produce something coherent. It's the closest thing I've found to "set it going and trust it" that's also genuinely safe to leave running.

So I built a junkie's tool for it

Running a single loop from the terminal is easy. Running several loops, editing their plan files, watching their output, and keeping track of which ones need my attention gets unwieldy fast. I was juggling terminal tabs and cat-ing state files like an animal. So I built Ralph Loop Junkie, a desktop app for people who, like me, got a little too into this.

It's a native app, React + TypeScript + Vite on the front end and Tauri 2 (Rust) on the back. Here's what it gives you:

  • A three-panel workspace. Your loops list, a file browser, and a real CodeMirror editor, so you can read and edit a loop's PRD.md, PROMPT.md, and tasks.json without leaving the app.
  • Full loop lifecycle. Create, rename, run, stop, delete, and "mark reviewed," all from the UI.
  • Status at a glance. idle / running / needs-review badges, an animated heartbeat for running loops, and live counts in the top bar.
  • Live logs. A drawer streams each loop's stdout/stderr as it runs, so you can actually watch the work happen.
  • Real file management. Add, rename, delete, drag-and-drop upload, and images even render inline in the editor. There's a one-click "Add task" helper for tasks.json.
  • Disk sync. Files are re-read from disk while a loop runs, so the edits the loop makes to its own state show up live in front of you.
  • A menu bar tray. Close the window and it hides to the tray so your loops keep running in the background, showing total / running / needs-review counts. This is the feature that turned it into an all-day, all-night habit.
  • A command palette (⌘K) and sensible keyboard shortcuts throughout, because I live in the keyboard.

And because the GUI shouldn't be the only way in, it ships with a companion CLI: a standalone ralph binary that operates on the same data directory as the app, so the two stay perfectly interoperable.

ralph list              # list all loops (name, id, status, iteration, last run)
ralph run <id|name>     # run a loop, streaming output to the terminal
ralph stop <id|name>    # stop a running loop

When you create a new loop, it's seeded with a minimal working example whose only task is to print Hi, I'm a loop. You can run one end-to-end the second you open the app and watch the whole machine turn over before you point it at anything real.

A note on guardrails

I want to be straight about this, because "autonomous agents shipping code all night" is the kind of phrase that should make a good engineer nervous. The reason I'm comfortable leaving these loops running is the verification step. A loop is only as trustworthy as the command in step 3, so the discipline is to put real tests there instead of true. The plan files, the inspectable state, and the "mark reviewed" workflow exist precisely so there's always a human checkpoint between "the loop thinks it's done" and "this is going to production." The whole design is built to keep autonomous work reviewable.

Try it

Ralph Loop Junkie is open source and on GitHub right now:

github.com/JordanDalton/ralph-loop-junkie

It's currently developed and tested on macOS, and getting started is the usual:

npm install
npm run tauri dev

If you've been curious about Ralph loops but didn't want to wire up the plumbing yourself, this is the fastest way in. Clone it, run the seeded example, then point a loop at something you actually want built — and go get lunch.

Star it if it's useful, open an issue if something's broken, and let me know what you build with it. Just one more iteration.


Written by Jordan Dalton. More at jordandalton.com.

Enjoyed this?

Book a build day.

Take the ideas in here from concept to working software in one focused day.

Book a build day →
jordandalton.com — © 2026 Jordan DaltonBuilt in a day, naturally.