A TypeScript library · local-first · zero dependencies

Durable execution for scripts and AI workflows.

Durably records completed steps to your filesystem, so rerunning a crashed script resumes unfinished work instead of repeating completed effects. Declare the policies once and Durably handles retry backoff, per-attempt timeouts, completed-step idempotency, pause and resume, rate limits, parallel and keyed concurrency, circuit breakers, failed-run inspection and retry, reverse-order compensations (sagas), fan-out/fan-in, durable waits, and priority scheduling for enqueued runs. Workflow results can decide what runs next in ordinary TypeScript; Durably records that path and resumes it safely.

Runtime
Node.js 20+ and Bun
Persistence
.durably/ on your filesystem
Operation
No server, daemon, or queue

Why it exists

Long scripts fail for ordinary reasons.

APIs flake. Terminals close. Machines sleep. Agent loops run longer than a single process should be trusted to survive. Starting from zero repeats completed effects and throws away useful progress.

Choose it deliberately

Use it for the script that should finish.

Good fit
  • Multi-step AI and data workflows
  • Long-running CLIs and local pipelines
  • Expensive or slow API sequences
  • Human approval and durable waits
  • Agent loops with budgets and checkpoints
Wrong fit
  • Distributed worker fleets
  • Job queues and event buses
  • Always-on cron or service scheduling
  • Payment or transaction orchestration
  • Workflows that need live multi-node execution

The whole mental model

Three rules, then normal TypeScript.

01

Put effects inside steps.

Network calls, model calls, and writes go in ctx.step(). Pure branching and transformation stay ordinary TypeScript.

02

Run the workflow.

run(workflow, input) persists to .durably/ and returns your workflow value directly—never a metadata wrapper.

03

Rerun after interruption.

The function replays from the top. Completed steps return recorded results; only unfinished work executes.

Agent-readable by default

An agent should know in one fetch.

The practical brief states when to use Durably, when not to, the replay rule, the typed core API, and a tested implementation pattern in approximately 2,000 GPT-style tokens (8.0 KB). The standalone full reference documents every advanced context member and operational API in approximately 4,600 tokens (18.7 KB).

Paste into your coding agent

Read the practical core at https://nikhil-verma.com/durably/llms.txt and use @nikhilverma/durably to make this TypeScript script resume safely after interruption. Keep all effects inside ctx.step(); do not introduce a server or worker system. Only load https://nikhil-verma.com/durably/llms-full.txt if the task needs loops, child workflows, waits, budgets, resources, engine operations, or custom storage.

Available when needed

Small entry point. Real workflow depth.

Start with workflow, run, step, parallel, and retry. The rest stays out of the way until the work asks for it.

Failure policyRetries, backoff, jitter, timeouts, validation
TopologyParallel steps, child runs, fan-out and fan-in
Long workDurable loops, sleeps, signals, and human approval
SafetyBudgets, compensation, circuit breakers, rate limits
TestingCrash injection, fake clock, and automatic shadow replay
StorageInspectible files by default; built-in node:sqlite adapter

Start with the default

Make one script resumable.

npm install @nikhilverma/durably