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

@dynoxide/wasm-engine

v0.11.3-preview

Published

The dynoxide DynamoDB-compatible engine compiled to WebAssembly, with a Web Worker client for running real DynamoDB operations in the browser. Preview.

Downloads

816

Readme

@dynoxide/wasm-engine

The dynoxide DynamoDB-compatible engine, compiled to WebAssembly and packaged to run in the browser. It carries the engine .wasm, the official @sqlite.org/sqlite-wasm SQLite build, the bundled Web Worker, and an EngineClient that drives them, so you can run real DynamoDB operations client-side against a SQLite-backed store persisted to OPFS.

It's a preview. The wasm build is not run against the conformance suite that backs dynoxide's native build, so treat its behaviour as illustrative rather than authoritative.

Install

npm install @dynoxide/wasm-engine

This is a preview build: the version carries -preview and the wasm path is not run against the conformance suite. npm install @dynoxide/wasm-engine gets the current preview; pin the exact version (0.11.1-preview) to lock to one.

Quick start

import { EngineClient } from "@dynoxide/wasm-engine";

const client = new EngineClient();
await client.ready();

await client.execute("CreateTable", {
  TableName: "Music",
  KeySchema: [
    { AttributeName: "artist", KeyType: "HASH" },
    { AttributeName: "song", KeyType: "RANGE" },
  ],
  AttributeDefinitions: [
    { AttributeName: "artist", AttributeType: "S" },
    { AttributeName: "song", AttributeType: "S" },
  ],
  BillingMode: "PAY_PER_REQUEST",
});

await client.execute("PutItem", {
  TableName: "Music",
  Item: { artist: { S: "Pixies" }, song: { S: "Debaser" } },
});

const { Items } = await client.execute("Query", {
  TableName: "Music",
  KeyConditionExpression: "artist = :a",
  ExpressionAttributeValues: { ":a": { S: "Pixies" } },
});

execute takes the operation name and a plain DynamoDB-JSON request, resolves with the response, and rejects with a typed EngineError. The client runs the engine in a Web Worker (OPFS's synchronous file handles are Worker-only) and owns the message round-trip, so you deal in objects rather than postMessage envelopes.

API

  • new EngineClient(opts?) - boots the engine eagerly. Calls queue behind boot, so you can issue work before ready() resolves.
  • await client.ready() - resolves with the boot descriptor ({ contractVersion, capabilities, persistenceMode }).
  • client.execute(op, request) - run one operation.
  • client.supports(op) - whether the engine implements an operation, for capability-gating your UI.
  • client.persistent - true when the session persists across reloads (OPFS), false in the in-memory fallback.
  • client.terminate() - tear the Worker down and reject any in-flight calls.

The package also exports EngineError (the engine's __type is on .type) and CONTRACT_VERSION. TypeScript declarations ship with it, so the client and its boot descriptor are typed out of the box.

Where the assets live

The Worker and the two .wasm travel inside the package. new EngineClient() with no arguments resolves the Worker next to this module, and the Worker resolves its .wasm next to itself, so a bundler that copies the package's files - or a plain static deploy of them - needs no configuration.

Serving the assets from a CDN or a different origin? Two options:

  • assetBase - the directory the assets sit in, e.g. new EngineClient({ assetBase: "https://cdn.example.com/dynoxide/" }).
  • workerUrl - the exact Worker URL, if it doesn't sit beside its .wasm under a shared base.

If you'd rather construct the Worker yourself - to let a bundler handle it, say - the package exposes it at the ./worker subpath. Build it and hand it back through createWorker:

new EngineClient({
  createWorker: () =>
    new Worker(new URL("@dynoxide/wasm-engine/worker", import.meta.url), { type: "module" }),
});

Two clients on one page are fine: each gets its own storage pool, keyed on name (default dynoxide.db), so give them distinct names if both should persist.

Hosting

The engine needs a secure context (HTTPS, or localhost for development) for OPFS, but no COOP/COEP cross-origin isolation. A Content-Security-Policy must allow 'wasm-unsafe-eval', or the engine won't instantiate. Serve the .wasm as application/wasm, and serve the assets gzip- or brotli-encoded - the wasm and the Worker both more than halve over the wire.

Versioning

CONTRACT_VERSION stamps the message-envelope shape, not the engine version. Adding an operation leaves it alone; changing a request, response, or error envelope bumps it. The client validates it against the engine on boot and fails loudly on a mismatch, so a pinned consumer fails with a clear error rather than mis-reading a newer engine. The shipped engine and contract versions sit in manifest.json. manifest.engineVersion is the dynoxide crate version (e.g. 0.11.1); the npm package version layers a -preview suffix on top (e.g. 0.11.1-preview), since the package is a preview distribution of that crate version.

Persistence

State persists across reloads via OPFS. Where OPFS synchronous access handles are unavailable (Firefox private windows, older Safari), the client falls back to an in-memory session and reports it through persistent / persistenceMode rather than failing.

Licence

MIT OR Apache-2.0. See LICENSE-MIT and LICENSE-APACHE.