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

@promptlyapp/sdk

v0.3.0

Published

Typed wrappers over the window.Promptly host API injected into every Promptly mini-app WebView.

Readme

@promptlyapp/sdk

Typed wrappers over window.Promptly, the host API injected into every Promptly app.

A Promptly app is a self-contained HTML/JS bundle running in a WebView on someone's phone. The Promptly runtime injects a global, window.Promptly, and that global is how the app reaches everything a sandbox cannot reach on its own: a shared database, the camera, payments, haptics, the signed-in user's profile, an AI model, and about thirty other capabilities.

This package is the typed surface of that global: one module per capability, with the exact contract of each method in its TSDoc. It is thin on purpose. The injected JavaScript is the behaviour; the types are the product.

npm install @promptlyapp/sdk

Not on the public npm registry yet. The first release has not been published, so that command answers E404 Not Found today. Until it lands, build a tarball from a checkout: Install in the repository README has the four commands, and everything below is identical either way.

Plain TypeScript compiled to ESM, so it imports under plain Node with no build step. svelte is an optional peer dependency, needed only by @promptlyapp/sdk/stores.

Entry points

| Import | What it gives you | |---|---| | @promptlyapp/sdk | Every capability namespace: ready, storage, db, game, realtime, invites, net, share, clipboard, haptics, camera, scanner, media, speech, audio, tts, torch, screen, notifications, geolocation, maps, biometric, health, nfc, sensors, contacts, calendar, files, ai, ads, payments, profile, plus the shared types. | | @promptlyapp/sdk/stores | Svelte-reactive helpers: theme, online, and watch() for a live db collection. | | @promptlyapp/sdk/testing | createFakePromptly(), a complete scriptable in-memory host. | | @promptlyapp/sdk/promptly-project.schema.json | The JSON Schema for a promptly.json project file. | | @promptlyapp/sdk/host.css | The host's base stylesheet, for a local dev host to inject so a previewed app matches Promptly. Generated from hostBaseCss(). | | @promptlyapp/sdk/design-tokens.json | The --promptly-* design tokens as data, for a non-JS consumer to read the palette without parsing CSS. |

The root export also carries the host contract the last two are generated from: hostBaseCss() returns that stylesheet as a string (the single definition the local dev host, the gallery and the starter all render against, so none of them keeps a copy that drifts from what Promptly serves), and hostDesignTokens() returns the palettes behind it.

A minimal example that runs anywhere

Outside the Promptly runtime there is no window.Promptly, so every call would throw. Install the fake host first and the same code runs under plain Node. Save as example.mjs, then node example.mjs:

import { createFakePromptly } from "@promptlyapp/sdk/testing";
import { db, ready, storage } from "@promptlyapp/sdk";

const fake = createFakePromptly({
  user: { username: "ada", displayName: "Ada", avatarUrl: null, bio: null },
});
fake.install(); // defines globalThis.Promptly, the same shape the runtime injects

const ctx = await ready();
console.log("running as", ctx.appId, "in", ctx.theme, "theme");

await storage.set("save", { level: 3 });
console.log("per-app storage:", await storage.get("save"));

const scores = db.collection("scores");
await scores.upsertMine({ score: 4820 }, { tag: "weekly", rank: 4820 });
const weekly = await scores.query({ tag: "weekly", orderBy: "rank", dir: "desc" });
console.log("leaderboard:", weekly.docs.map((doc) => [doc.owner?.username, doc.rank]));

fake.uninstall();

Testing an app

The fake implements db, game, realtime and storage for real: owner semantics, watch events on every write, and moves validated through your own game.define() spec. Everything a user or a device would decide is a queue or a switch instead. An empty queue resolves that call's documented cancel or deny default, so an untouched fake behaves like a user who says no to everything.

import { createFakePromptly } from "@promptlyapp/sdk/testing";

const fake = createFakePromptly({ user: { username: "ada", displayName: "Ada", avatarUrl: null, bio: null } });
fake.install();

fake.enqueue.camera("data:image/png;base64,AA=="); // next capture() "takes" this photo
fake.enqueue.biometric({ verified: false, error: "locked_out" });
fake.setTheme("dark");                             // the theme store flips live
fake.setOnline(false);                             // the online store flips live
fake.seedDoc("scores", { score: 99 }, { tag: "weekly", rank: 99 });

expect(fake.calls).toContainEqual({ method: "tts.speak", args: ["hello"] });
fake.uninstall();

Permissions, cancellation and unavailability

Three things the types will make you handle, and the host will enforce whether you handle them or not:

  • Permissions. Gated capabilities need a permission token declared in the app manifest. The token for each namespace is recorded in that module's TSDoc: camera for both camera and scanner, photos for media, microphone for speech, and so on. db, storage, game, realtime, net, theme and locale are ungated.
  • Cancellation. Every picker resolves null when the user cancels or denies, and the return type says so. There is no separate error path to catch.
  • Unavailability. Capabilities that a given device may simply not have (health, nfc, and friends) can resolve an Unavailable value. Narrow it with isUnavailable().

Licence

MIT. Full documentation, including the components package and the gallery, is in the repository README.