> ## Documentation Index
> Fetch the complete documentation index at: https://loop-js.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Why loop.js

> Claude Code already loops — /goal, /loop, and /schedule. Use them for yourself; use loop.js when the loop is a system you ship.

Claude Code ships three ways to make an agent repeat, right in the terminal
([Anthropic's loop taxonomy](https://claude.com/blog/getting-started-with-loops)):

* **`/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

|                               | `/goal`                          | `/loop`                                    | `/schedule`                        | loop.js                                                                                               |
| ----------------------------- | -------------------------------- | ------------------------------------------ | ---------------------------------- | ----------------------------------------------------------------------------------------------------- |
| Who judges "done"             | an evaluator in the same session | the working model itself                   | each run ends when its agent stops | a separate, skeptical **Verify** agent — own model, read-only — and only its Verdict settles the Loop |
| Where memory lives            | the session's context window     | the session — stops when your machine does | carried by your prompt, run to run | on disk — Record, journal, handoff notes; every Round starts with fresh context                       |
| Crash, restart, overlap       | tied to the live session         | tied to the live session                   | fire-and-forget                    | the **Lock** (CAS + heartbeat): a live owner refuses overlap, a dead one is taken over                |
| What stops a runaway          | a maximum number of turns        | you cancel it                              | you cancel it                      | total `usd` ledger (step-granular), Rounds cap, per-Round timeout — each a typed Exit                 |
| A finished goal, re-triggered | —                                | runs again                                 | runs again                         | re-judged through the **Verify gate** — near-free while still ok, re-opens when stale                 |
| Surface                       | a command inside Claude Code     | a command inside Claude Code               | a command inside Claude Code       | a typed library — `Loop.define` / `loop.run`, an event stream, CLI exit codes                         |

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

|                    | `/goal`                          | loop.js                                                      |
| ------------------ | -------------------------------- | ------------------------------------------------------------ |
| The judge          | an evaluator inside your session | a separate Verify session — own model, read-only permissions |
| Feedback           | —                                | a mandatory `reason` on every verdict, fed to the next Round |
| An unmeetable goal | runs to the turn cap             | settles as an explicit give-up (`impossible`)                |
| Lifetime           | ends with your session           | resumes from disk — any machine, any trigger, weeks later    |

## What the convergence machinery buys you

<CardGroup cols={2}>
  <Card title="Only a verdict settles" icon="gavel" href="/concepts/loop">
    A separate Verify agent — its own model, read-only permissions — judges every Round.
    Rounds, dollars, and timeouts are guards, never a definition of done.
  </Card>

  <Card title="State on disk" icon="database" href="/concepts/loop">
    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.
  </Card>

  <Card title="Declared guards" icon="shield" href="/concepts/limits">
    `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.
  </Card>

  <Card title="One writer per Workspace" icon="lock" href="/api/run">
    `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.
  </Card>

  <Card title="Schedulers, not daemons" icon="clock" href="/cli/cron">
    `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.
  </Card>

  <Card title="Embed it, too" icon="code" href="/api/events">
    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.
  </Card>
</CardGroup>

## The same agents, judged

loop.js is not a different agent — Execute and Verify run on the
[Claude Agent SDK](https://code.claude.com/docs/en/agent-sdk), the engine behind Claude
Code. What loop.js adds is the machinery around them:

```ts theme={null}
import { Loop } from "@loop.js/core"

const loop = Loop.define({
  goal: "Make `bun test` pass on ./api",
  verify: { model: "claude-haiku-4-5" }, // the judge runs cheaper, read-only
  limits: { rounds: 10, usd: 5, timeout: "15m" },
})

const run = loop.run()
for await (const e of run) {
  if (e.type === "verdict") console.log(`round ${e.round}:`, e.ok, e.reason)
}

const exit = await run.done()
// { settled: true, verdict } — the judge said so, not the worker
```

```sh theme={null}
npx loop cron add "*/30 * * * *" --until settled   # keeps trying, removes itself when the bar is met
```

## 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.

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/quickstart">
    From empty directory to a settled Goal.
  </Card>

  <Card title="What is loop engineering" icon="infinity" href="/loop-engineering">
    The practice loop.js is built for — and where it stands in it.
  </Card>
</CardGroup>
