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

pi-wasm-kit

v0.2.0

Published

Pi Durable inside a QuickJS WebAssembly sandbox, with browser and Node hosts.

Readme

Browser playground

The actual upstream Pi Durable engine runs inside QuickJS WASM. The host supplies a model transport, an exclusive durable journal, and explicitly granted tools. Stop the process or terminate the Worker, reopen the same journal, and Pi resumes unfinished tasks from committed checkpoints.

Experimental, v0.2. Browser and Node hosts, plus iOS and Android WebView examples. Mobile examples run the same WASM engine on-device and call an actual Swift/Java tool. They load assets from a development server; they are not standalone offline apps. PostgreSQL and standalone WASI execution are not implemented.

This is an independent project inspired by PiDurableKit’s Apple embedding design, not an official port or an endorsed project. PiDurableKit uses JavaScriptCore; this project uses QuickJS compiled to WebAssembly.

Install

| Platform | Get started | | --- | --- | | macOS / Windows / Linux · Node.js | Install the SDK from npm | | Browser | Run the playground | | iOS 26+ | Build the Swift example on macOS | | Android API 26+ | Build and install the Android example |

npm install pi-wasm-kit

Requires Node.js 22.19+. This installs an SDK in your application, not a desktop/mobile app or a global CLI. See the platform installation guide for prerequisites, Windows PowerShell commands, device setup and checksums.

Try it

Requires Node.js 22.19+ and a modern browser with IndexedDB and Web Locks (HTTPS or localhost).

git clone https://github.com/leepokai/pi-wasm-kit.git
cd pi-wasm-kit
npm ci
npm run build
npm run dev

Open the local URL. The demo uses a deterministic local model, not an LLM: every prompt demonstrates multiplying 21 by 2, with delayed model responses so you can interrupt it. The Pi engine, tool execution, WebAssembly, storage, and recovery are real.

  1. Click Run.
  2. While running, click Interrupt runtime. This actually terminates the Worker.
  3. Click Reopen & resume. The existing journal is reopened.
  4. Refresh the page. The saved conversation remains.

Optionally enter an OpenAI Chat Completions-compatible endpoint and model in Model connection, then interrupt and reopen. The endpoint must allow your origin through CORS. Use your own authenticated backend proxy; this demo has no login and does not store API keys. The endpoint and model selection are retained in localStorage so refreshing uses the same transport.

Mobile examples

  • iOS / Swift — WKWebView, native tool, app-relaunch recovery, and iOS 26+ BGContinuedProcessingTask.
  • Android / Java — Android WebView, origin-scoped native tool, process-restart recovery.

The mobile guide explains asset hosting, platform limits, and how to reproduce the native E2E checks. Background execution is separate from durability: a saved task can survive an interruption without receiving more background CPU time.

Node example with a real model

PI_MODEL=your-model PI_API_KEY=your-key \
PI_BASE_URL=https://your-compatible-provider.example/v1 \
node examples/node/chat.mjs 'Hello from WASM'

PI_BASE_URL defaults to https://api.openai.com/v1. Credentials stay in the host transport and are not passed to the WASM guest. Journals contain prompts, model responses, tool arguments/results and application state; handle them as sensitive data.

Use the SDK

Install from npm with npm install pi-wasm-kit. For an exact version, use npm install [email protected]. You can also build from source with npm pack, or install the tarball from the GitHub release.

import { PiWasmAgent } from 'pi-wasm-kit';
import { openNodeJournal } from 'pi-wasm-kit/node';
import { openAICompatible } from 'pi-wasm-kit/openai';

const agent = await PiWasmAgent.open({
  journal: await openNodeJournal('./agent.jsonl'),
  model: openAICompatible({
    baseURL: process.env.PI_BASE_URL!,
    model: process.env.PI_MODEL!,
    apiKey: process.env.PI_API_KEY,
  }),
  tools: [{
    name: 'multiply',
    description: 'Multiply two numbers',
    parameters: {
      type: 'object',
      properties: { a: { type: 'number' }, b: { type: 'number' } },
      required: ['a', 'b'],
    },
    replay: 'safe', // Only for operations safe to repeat after interruption.
    execute: ({ a, b }, { signal, output, taskId }) => {
      signal.throwIfAborted();
      output('Calculating…');
      return String(Number(a) * Number(b));
    },
  }],
  onEvent(event) {
    if (event.type === 'events') console.log(event.events);
  },
});

try {
  const { id } = await agent.submit('Multiply 21 by 2', 'request-001');
  await agent.wait(id);
  console.log(await agent.view());
} finally {
  await agent.close();
}

In a browser Worker, replace openNodeJournal with openBrowserJournal from pi-wasm-kit/browser. Use a bundler such as Vite to serve the QuickJS WASM assets. The included demo shows the complete Worker bridge. Do not run CPU-bound guest code on the UI thread.

model can be any host function returning a Pi AssistantMessage. Its third argument accepts Pi AssistantMessageEvent values for incremental text, thinking and tool-call updates. The supplied HTTP adapter currently buffers Chat Completions responses; use a streaming ModelHandler for token-level events. The final message is returned from the handler; the bridge emits its terminal event.

What is preserved from PiDurableKit?

The goal is to retain Pi’s capabilities rather than replace its scheduler with a simplified loop. See the feature matrix for exact boundaries.

| Capability | Available here | | --- | --- | | Durable conversations and interrupted-run recovery | Upstream Pi + persisted journal | | Input deduplication, steering, follow-ups | submit, submitDraft, whenBusy | | Configuration, reset, fork and compaction | First-class host methods | | Host tools, schema validation, progress and cancellation | JSON bridge, explicit host capabilities | | Safe/unsafe tool replay | Upstream Pi policy, safe requires opt-in | | Events, usage, task inspection and graph | onEvent, watch, view, inspect, taskGraph | | JS extensions, tools, prompt sections, hooks and wrappers | CommonJS extension sources inside WASM | | Documents, transactions, custom/child tasks and subagents | Upstream API inside extensions and evaluate | | Apple Keychain, OAuth helpers, native filesystem/shell | Host integration required; not bundled | | Android / iOS app integration | Origin-scoped native tool bridges, persistent WebView journals; examples | | iOS continued background processing | iOS 26+ adapter, progress, expiration and durable cancellation; device scheduling remains system-controlled |

Extensions and advanced Pi APIs

Install a CommonJS source string at open time. Supported require names are @earendil-works/pi-durable, @earendil-works/pi-ai (Type only) and @earendil-works/chord/context.

const agent = await PiWasmAgent.open({
  journal,
  model,
  extensions: [counterExtensionSource],
});

See the counter extension: a tool, prompt section, wrapper, transactionally deduplicated document mutation, and custom durable task. Definitions must be installed again on recovery; the journal stores task kinds and checkpoints, not executable source code. install(source) and uninstall(name) change the live registry.

For advanced integration, evaluate(source, args, conversationId?) runs a trusted async function body inside WASM. It receives pi, Type, harness, conversation, registry, context, and JSON args. This exposes the upstream document, task, hook and transaction APIs without attempting to serialize functions across the boundary.

const taskId = await agent.evaluate<number>(`
  const task = registry.snapshot().task('example.double');
  return conversation.commit(tx => tx.createTask(task, args, {
    ownership: { kind: 'conversation' }
  }), context);
`, { value: 21 });
const result = await agent.waitForTask(taskId);

Extension source and evaluate are trusted application code, not a multitenant plugin security boundary. Extensions share one guest and its granted capabilities. Do not evaluate arbitrary user/model-generated code with powerful host tools. See architecture and durability and the API guide.

Validation

npm test                         # Real WASM integration tests + local HTTP transport
npx playwright install chromium
npm run build:demo               # Production browser bundle
npm run test:e2e                  # Production Worker termination, reload, exclusion
npm run typecheck
npm run test:package              # Install the tarball into a clean consumer

Tests use synthetic model responses and a local HTTP fixture. They do not require paid credentials or claim to validate a live provider’s service. CI repeats the suite on Linux. Recovery is at committed task boundaries, not a snapshot of a JavaScript stack or an in-flight HTTP connection.

Credits and license

This project is MIT licensed. See LICENSE, NOTICE, and third-party notices. Builds include dist/licenses with the license texts for bundled dependencies. Upstream licenses remain applicable.