npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

workflow-world-browser

v0.1.0

Published

A Workflow SDK World that runs in the browser: IndexedDB storage, a durable queue consumed by one tab at a time, and streams over BroadcastChannel.

Readme

workflow-world-browser

A Workflow SDK World that runs in the browser. Durable runs, steps, hooks, waits, and streams live in IndexedDB, and the queue is consumed by whichever tab holds a Web Lock, so a workflow keeps going across reloads and tab closes with no server.

  • Storage: IndexedDB. Each events.create is one IndexedDB transaction over the run, its log, and the entities it touches. IndexedDB serializes overlapping transactions across tabs, which gives the World contract's dense, commit-time slot allocation (bump and report included) without a server.
  • Queue: durable rows in IndexedDB. A message is deleted only after its delivery returns, so closing the tab mid-delivery leaves it for the next tab. One tab consumes at a time (navigator.locks); the others enqueue.
  • Streams: IndexedDB rows, tailed live through BroadcastChannel hints.
  • Semantics follow @workflow/world-local, the reference World: idempotent run_started, terminal-state rules, born-running step_started, hook token claims and hook_conflict, (runId, resumeId) resume dedup, retryAfter, sinceCursor deltas, and preloaded logs on run_started.

Try it

Live demo: https://pranaygp.github.io/workflow-world-browser/

Press Start a run, then Crash this tab while a step is running: the page reloads, re-acquires the Web Lock, redelivers the in-flight queue message, and the step runs again as attempt 2 before the run completes. Or press Open a second tab, start a run there, and close the driving tab mid-step: the second tab takes over. The demo shows the event log, the queue rows, and the lock state as it goes.

The demo drives the World with a small runner written against the World interface, not the Workflow SDK runtime, which does not run in a browser. examples/demo explains why and lists the exact steps.

Install

npm install workflow-world-browser

Use it in a tab

import { createWorld } from 'workflow-world-browser';

const world = await createWorld({ name: 'my-app' }); // one IndexedDB database = one World
world.createQueueHandler('__wkf_workflow_', async (message, meta) => {
  // your runtime's queue consumer
});
await world.start();

In a tab, deliveries call the registered handler directly. Model calls or any other secrets-bearing work should go through your own server; the World itself never needs one.

Use it under a server (tests, SSR)

Set WORKFLOW_TARGET_WORLD=workflow-world-browser. Outside a browser the World falls back to fake-indexeddb, which is in-memory: data lasts as long as the process. The queue then delivers over HTTP to the app's workflow route (/.well-known/workflow/v1/flow on http://localhost:$PORT, or WORKFLOW_BROWSER_BASE_URL), the same way @workflow/world-local does.

| Variable | Default | Meaning | | --- | --- | --- | | WORKFLOW_BROWSER_DB_NAME | workflow-world | IndexedDB database name (outside a browser; in a tab pass name). | | WORKFLOW_BROWSER_BASE_URL | http://localhost:$PORT | Where the queue delivers when not in a browser. |

Compatibility

pnpm test builds the package and runs the Workflow SDK's World compatibility suite, @workflow/world-testing (pinned to 5.0.0-beta.57), against dist/, plus unit tests for slot allocation, hook tokens, and queue durability. All 14 compatibility tests pass.

Tested with @workflow/[email protected] and @workflow/[email protected] on Node.js 22. Not tested against Workflow 4.x.

Not implemented: encryption (getEncryptionKeyForRun), hook retention, the invoke capability, createBatch, and runs.waitForTerminalStatus. The runtime feature-detects all of them.

License

Apache-2.0