Skip to content
PluginStats

@gnldev/workflow weekly downloads statistics

By gnldev (7 listings) · npm · AI SDKs

Durable deterministic workflows: each step journaled exactly-once, crash→resume picks up where it left off.

View on npm Fresh · Oct 18, 2026

@gnldev/workflow has 460 recorded weekly downloads on npm, ranking #1560 of 2,322 tracked listings.

Weekly downloads
460
Official API · Oct 18, 2026
7-day growth
—
Insufficient history
30-day growth
—
Insufficient history
90-day growth
—
Insufficient history
Rank
#1560
Among tracked npm listings

About @gnldev/workflow

@gnldev/workflow

Durable deterministic workflows — every step's result is journaled, so a crash → resume picks up where it left off instead of re-running the finished steps (at-most-once for side effects). Control flow: then / parallel / branch / foreach / loop. Suspendable: runResumable + sleep / waitFor (evented + scheduled).

Install: pnpm add @gnldev/workflow — or use it from a repo clone: pnpm install && pnpm -r build.

npm i @gnldev/workflow   # journal: @gnldev/durable
import { workflow, step } from '@gnldev/workflow';
import { SqliteStorage } from '@gnldev/durable/sqlite';

const fetchUser = step('fetchUser', async (id: number) => ({ id, name: 'Ada' }));
const greet = step('greet', async (u: { name: string }) => `Hello ${u.name}`);

const wf = workflow<number>().then(fetchUser).then(greet);

const out = await wf.run(1, { runId: 'w1', journal: new SqliteStorage('runs.db').runs });
// Crash → run again with the same runId → completed steps come back from the journal, continuing where it left off.

API

  • workflow<I>() → builder: .then(step) · .parallel([a, b]) · .branch(pred, ifStep, elseStep) · .foreach(...) · .loop(...)
  • step(id, async (input, ctx) => out) — every step journaled; a completed step is replayed, not re-run, whatever it returned (undefined included)
  • a step id is unique within one workflow: .then(inc).then(inc) throws at build time. Reuse the body under a second id: .then(step('inc-2', inc.run)). The two arms of a branch and a nested workflow (asStep) may reuse an id
  • wf.run(input, { runId, journal }) — one-shot
  • wf.runResumable(input, ctx) — for suspending steps (sleep / waitFor); suspends with WorkflowSuspended, resumes on event/time.

How it works

Each step's output is journaled under ${runId}:wf:${stepId} → the step doesn't rerun on replay. An output of undefined is stored as { __gnlStepRecord: 'void' } (a stored undefined reads back like a missing key), and an output that itself has a __gnlStepRecord key is stored wrapped, so every output replays as exactly what the step returned. Reading step records yourself? decodeStepRecord(v) from @gnldev/durable gives back the output; isVoidStepRecord(v) recognises the void record. Two step uses that would share one journal key — the same id twice, a top-level pay:check next to asStep('pay') with an inner check, a step named like a retry's <id>:attempts, or one of the engine's own keys (_suspend, _canceled, _input, _resume:*) — are refused where the workflow is built, and the error names the rename that separates them. parallel sub-steps are journaled individually; branch/loop preserve deterministic replay.

Side-effect steps (the crash window, closed)

Plain steps journal their output AFTER running — a crash between an external effect (an HTTP POST, a charge) and the journal write leaves no record, and the resume re-fires the effect. Declare the effect and the engine writes a write-ahead claim before executing:

step('charge', async (input, ctx) => {
  // ctx.idempotencyKey === `${runId}:wf:charge` — carry it to the provider (Stripe Idempotency-Key)
  // and the journal's dedup extends downstream, to the provider itself.
  return chargeCard(input, { idempotencyKey: ctx.idempotencyKey });
}, {
  sideEffect: true,
  recover: async (input, { idempotencyKey }) => {         // the crash-window answer: ask the provider
    const found = await lookupCharge(idempotencyKey);
    return found ? { done: true, output: found } : { done: false };
  },
  claimTtlMs: 60_000,   // presume in-flight this long; calibrate ABOVE the step's worst case
});

Resume state machine: output present → replay; claim absent → run; claim live → StepRetryBlockedError (state: 'in-flight', clears by itself); claim stale or the attempt threw → recover is asked first — {done:true} journals the found output without re-running, {done:false} re-runs safely; no recover → 'unresolved': the engine refuses to guess. Manual exits for 'unresolved': effect LANDED → journal.put(detail.key, output); effect NEVER fired → journal.put(detail.key + ':_claim', { startedAt: Date.now(), released: true }). A clean suspend re-runs on resume (the documented contract); retry() carries the declaration and consults recover BETWEEN in-process attempts — without recover, a side-effect step's first throw propagates instead of blind-re-firing. Combinators (parallel/branch) carry the declaration through; foreach/loop bodies are bare functions with NO durability surface — put the effect in a step(..., { sideEffect: true }) inside a nested workflow (asStep) if an iteration needs the claim protocol.

License

Apache-2.0 — see LICENSE.

Description from the npm listing.

  • ai
  • agent
  • llm
  • typescript
  • ai-sdk
  • durable
  • exactly-once
  • orchestration
  • steps
  • saga

README badge

Show your rank in a README or on your website. The badge updates automatically.

Charts

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

Adoption over time

@gnldev/workflow weekly downloads on npm, last 90 days: 460 weekly downloads as of Oct 18, 2026.@gnldev/workflowWeekly downloads on npm · Last 90 days460downloads / week400420440460480500520Jul 20Aug 4Aug 19Sep 3Sep 18Oct 3Oct 18downloads / weekOct 18, 2026 – Oct 18, 2026 · 1 observations · Updated Oct 18, 2026pluginstats.com
@gnldev/workflow weekly downloads on npm, last 90 days: 460 weekly downloads as of Oct 18, 2026.

7/30/90-day growth

@gnldev/workflow weekly downloads growth on npm: 7-day growth unavailable, 30-day growth unavailable, 90-day growth unavailable.@gnldev/workflowWeekly downloads growth on npm460downloads / week now7-day growthinsufficient historyInsufficient history30-day growthinsufficient historyInsufficient history90-day growthinsufficient historyInsufficient historyGrowth vs. nearest observation to each baseline date · Updated Oct 18, 2026pluginstats.com
@gnldev/workflow weekly downloads growth on npm: 7-day growth unavailable, 30-day growth unavailable, 90-day growth unavailable.

Ranking history

@gnldev/workflow npm ranking history: currently #1560 (by weekly downloads).@gnldev/workflownpm ranking · by weekly downloads · Last 90 days#1560current rank#1558#1559#1560#1561#1562Jul 22Aug 6Aug 21Sep 5Sep 20Oct 5Oct 20rankOct 20, 2026 – Oct 20, 2026 · 1 observations · Updated Oct 18, 2026pluginstats.com
@gnldev/workflow npm ranking history: currently #1560 (by weekly downloads).

Listing placement

All npm2,320 listings · 116 pages · 1,161 shown · page 79, #3 (overall #1,563)
All npm: every listing in weekly downloads order

Listing placement

AI SDKs259 listings · 13 pages · page 9, #16 (overall #176)
AI SDKs: every listing in weekly downloads order

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.

Each band is one page of 20. Weekly downloads on a linear 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.

Recent observations

Full history (1)
Recent weekly downloads observations for @gnldev/workflow
Date (UTC)Weekly downloadsChange vs. previous
460—

Similar npm AI SDKs plugins

All 20 @gnldev/workflow alternatives

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/workflow. First seen Oct 20, 2026; last successful collection Oct 20, 2026. See the methodology.