Skip to content
PluginStats

@gnldev/durable weekly downloads statistics

By gnldev (2 listings) · npm · AI SDKs

Call-scoped exactly-once effect + deterministic-replay durability layer for Vercel AI SDK agents. Drop-in: generateText -> runDurable.

View on npm Fresh · Oct 17, 2026

@gnldev/durable has 34 recorded weekly downloads on npm, a decrease of 51.4% over the past 30 days.

It ranks #1785 of 2,251 tracked npm listings by weekly downloads.

PluginStats has 121 daily observations since Jun 19, 2026; the latest is from Oct 17, 2026.

Weekly downloads
34
Official API · Oct 17, 2026
7-day growth
-89.5%
-290 weekly downloads
30-day growth
-51.4%
-36 weekly downloads
90-day growth
—
Insufficient history
Rank
#1785
Among tracked npm listings

About @gnldev/durable

@gnldev/durable

Call-scoped exactly-once effect + deterministic-replay durability for Vercel AI SDK agents.

Wraps the AI SDK's agent loop (generateText/streamText) without changing it. After a crash/restart a completed tool call is never executed a second time, and the agent makes the same decisions (deterministic replay). The one thing neither other agent frameworks nor plain AI SDK give you structurally: correctness.

The precise guarantee is at-most-once for a side effect, because the crash window between executing a tool and journaling its result cannot be closed by any client-side library — see the callout below. gnl's answer to that window is to refuse to guess: it blocks and asks, rather than silently re-running or silently continuing.

Install: pnpm add @gnldev/durable — the storage adapters ship inside the same package. (Or clone the repo and pnpm install && pnpm -r build.)

Durability in 2 lines

If the process crashes mid-turn, call again with the same runId → it resumes where it left off, the card is never charged a second time:

One id is one JOB, never one session. runDurable is the raw surface: the string you pass *is* the identity, so a sessionId or a conversation id there makes every later turn replay the first one forever. Through createGnl you name the work instead (workKey) and the engine derives the id — see Work identity.

What "never charged twice" actually means: the guarantee is at-most-once. If a step already completed, it's replayed and skipped. But if the crash lands in the narrow window *after* the charge executed and *before* its success was journaled, resume can't know whether the charge went through — so for a side-effect tool with no recover() and no idempotent/approval, it does not silently re-run and does not silently continue: it blocks and asks a human. Safe direction (never a double charge), but resume is not always seamless.

Concretely, runDurable throws SideEffectRetryBlockedError — it does not come back in result.interrupts, which carries approval suspensions only. Catch it:

recover() is the way to avoid the human: it re-checks the provider and must return { done: true, output } or { done: false }. Any other shape is treated as "could not determine" and lands back on this same gate rather than re-running the effect.

If you know generateText, you already know this — same arguments, same return type. The only addition: runId + journal.

How it works

• durableTool — wraps a tool's execute. The key is the toolCallId the AI SDK assigns; on replay the model response is reproduced verbatim, so the same id is generated → a tool that already succeeded never runs again. • withDurableModel — via a wrapLanguageModel middleware, records every model response to the journal and replays it on resume → the agent reproduces the same tool chain. • Journal — an append-only log. InMemoryJournal (dev) · SqliteStorage().runs (prod, node:sqlite, zero native dependencies).

Guarantee: a side effect is never repeated for the same toolCallId (call-scoped, replay/resume-safe). Not "the LLM always produces the exact same text" — if there's a recorded entry, it's replayed; everything past the crash point runs live. A call whose outcome is unknown (after a crash/timeout) is first checked against the provider via tool.recover?(); if it's still unknown, the system **blocks and asks for approval instead of silently retrying** (see "Human-in-the-loop").

Scope caveat (important): the default dedup is keyed by toolCallId. If the model re-plans the *same business action* under a new toolCallId (with identical or slightly different args — a documented AI SDK pattern), the call-scoped key does not collapse it. With identical args the default limits.sideEffectDuplicates: 'suspend' stops the repeat and asks a human — without a key nothing can tell "the same work again" from "two of the same, on purpose". With *different* args it is a new call. For "this action happens once" without a question, give the tool its identity: idempotency: 'args' / idempotencyKey (next section). A tool that declares no sideEffect is treated as one — declare sideEffect: false on a read tool.

A run outlives its caller (createGnl)

A registry run — gnl.run(), gnl.stream(), and every door built on them — executes apart from the call that started it, on the process's executor (one per process per store). The caller follows it.…

Description from the npm listing.

  • ai
  • agent
  • llm
  • typescript
  • ai-sdk
  • durable
  • exactly-once
  • journal
  • replay
  • idempotency
  • crash-recovery

Where @gnldev/durable sits in the listing

Each band is one page of 20. Weekly downloads on a log scale. Placement is projected from weekly downloads, so it can differ from the marketplace's own sort order. Hover a dot to see the listing.

All npm2,248 listings · 113 pages · page 90, #6 (overall #1786)
All npm: every listing in weekly downloads order
PNG SVG
AI SDKs249 listings · 13 pages · page 13, #4 (overall #244)
AI SDKs: every listing in weekly downloads order
PNG SVG

Charts

Images: 30d · 1y · all time · 1600×900 dark

Adoption over time

@gnldev/durable weekly downloads on npm, last 90 days: 34 weekly downloads as of Oct 17, 2026.@gnldev/durableWeekly downloads on npm · Last 90 days34downloads / week02004006008001K1.2K1.4K1.6KJul 19Aug 3Aug 18Sep 2Sep 17Oct 2Oct 17downloads / weekobservedarchived (Internet Archive)no observationsJul 21, 2026 – Oct 17, 2026 · 89 observations · Updated Oc…pluginstats.com
@gnldev/durable weekly downloads on npm, last 90 days: 34 weekly downloads as of Oct 17, 2026.
PNG SVG

7/30/90-day growth

@gnldev/durable weekly downloads growth on npm: -89.5% over 7 days, -51.4% over 30 days, 90-day growth unavailable.@gnldev/durableWeekly downloads growth on npm34downloads / week now7-day growth-290 weekly downloads-89.5%30-day growth-36 weekly downloads-51.4%90-day growth+34 weekly downloadsInsufficient historyGrowth vs. nearest observation to each baseline date · Updated Oct 17, 2026pluginstats.com
@gnldev/durable weekly downloads growth on npm: -89.5% over 7 days, -51.4% over 30 days, 90-day growth unavailable.
PNG SVG

Ranking history

@gnldev/durable npm ranking history: currently #1785 (by weekly downloads).@gnldev/durablenpm ranking · by weekly downloads · Last 90 days#1785current rank#1783#1784#1785#1786#1787Jul 20Aug 4Aug 19Sep 3Sep 18Oct 3Oct 18rankOct 18, 2026 – Oct 18, 2026 · 1 observations · Updated Oct 17, 2026pluginstats.com
@gnldev/durable npm ranking history: currently #1785 (by weekly downloads).
PNG SVG

Filled points are observed values; hollow points come from Internet Archive snapshots of the listing page. Dashed segments span periods with no observations — values between points are not interpolated.

Recent observations

Full history (121)
Recent weekly downloads observations for @gnldev/durable
Date (UTC)Weekly downloadsChange vs. previous
34-12
46+13
33-10
43-15
580
58-259
317-7
324-6
330-26
356-123
479-419
898-203
1,101+257
844—

Similar npm AI SDKs plugins

Data source

Weekly downloads (trailing 7 complete days) come from the official npm downloads API. Downloads include CI and mirrors and are not equivalent to installs or users. npm publishes no ratings.

Listing: https://www.npmjs.com/package/@gnldev/durable. First seen Oct 16, 2026; last successful collection Oct 18, 2026. See the methodology.