Skip to main content
Claude Code ships three ways to make an agent repeat, right in the terminal (Anthropic’s loop taxonomy):
  • /goal — a goal-based loop in your live session: an evaluator checks your success criteria each iteration, until the goal is achieved or a maximum number of turns is hit.
  • /loop — a time-based loop on your machine: re-run a prompt on an interval, or let the model pace itself.
  • /schedule — the same idea in the cloud: agents (routines) that run on a cron.
For a developer driving their own session, these are the right tool: one line, zero setup, and you’re watching the work happen. loop.js exists for the day the loop stops being something you run and becomes something you ship — a system with a bar to meet, a budget to respect, state to keep, and no human watching. The distinction in one sentence: /goal, /loop, and /schedule are commands inside Claude Code; loop.js is the same convergence discipline as a framework — a typed engine you run from any terminal, install on a schedule, or embed via Loop.define / loop.run / typed events. Everything a loop needs to reach done — an independent verdict, durable state, declared guards, real scheduling — in one npm package, driving the same Claude agents underneath.

What each owns

The nearest sibling is /goal — it, too, refuses to let the worker declare victory early. The differences, side by side:

What the convergence machinery buys you

Only a verdict settles

A separate Verify agent — its own model, read-only permissions — judges every Round. Rounds, dollars, and timeouts are guards, never a definition of done.

State on disk

Fresh context every Round; memory read back from disk. The loop survives crashes, restarts, and weeks on a schedule — it’s as durable as your filesystem.

Declared guards

rounds, usd, and a per-Round timeout bound the loop. Every ending is a typed Exit — a wrapper branches on exit codes, not on parsed output.

One writer per Workspace

run() claims the Lock atomically and throws LoopBusy at a live owner. Any Trigger cadence is safe — a periodic schedule doubles as the crash watchdog.

Schedulers, not daemons

loop cron installs Entries into crontab, launchd, Task Scheduler, or Modal — and an Entry declares its own lifetime: --until settled removes itself at the first settle.

Embed it, too

An async-iterable Run handle and a self-describing, replayable event stream — the same engine the CLI drives, as a typed library inside your product.

The same agents, judged

loop.js is not a different agent — Execute and Verify run on the Claude Agent SDK, the engine behind Claude Code. What loop.js adds is the machinery around them:

When to keep /goal, /loop, and /schedule

Honestly: often. Watching a refactor converge in your own session (/goal), re-checking a deploy every five minutes (/loop), a personal daily routine (/schedule) — an interactive command beats a framework. Reach for loop.js at the first of: the loop outlives your session, someone else (or cron) triggers it, money is on the line, or “done” must be judged by an agent the worker can’t influence.

Quickstart

From empty directory to a settled Goal.

What is loop engineering

The practice loop.js is built for — and where it stands in it.