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

@moku-labs/system

v0.1.1

Published

Isomorphic system API for Moku — store, notify, clipboard, tray, and deep-link capabilities via an env-style provider pattern (Tauri provider when the shell is detected, web fallback otherwise). Same island code runs on web and native.

Downloads

53

Readme

@moku-labs/system

One system API, two runtimes — the same island code talks to the OS on native and degrades honestly on the web.

Isomorphic system capabilities for Moku apps — store, tray, notify, clipboard, and deep-link — behind an env-style provider seam: a Tauri provider when the native shell is detected, a web provider otherwise. Your islands never branch on the runtime; a capability that cannot work where it runs says so as typed data (SystemResult), never as a thrown surprise. It is not a UI framework and not a Tauri wrapper — it is the seam between your app and whatever shell it happens to be running in.

npm types for @moku-labs/core node license: MIT

Install · Quick start · Plugins · The SystemResult contract · Usage · Development


Why @moku-labs/system

  • One codebase, web and native. Every capability selects its provider once at startup (Tauri shell detected → native, otherwise → web). Island code calls the same app.store.get(...) everywhere — no second code path to keep in sync.
  • Degraded capability is data, never a throw. Every method returns SystemResult<T>{ ok: true, value } or { ok: false, reason } with a typed reason (unsupported / denied / unavailable / error). Tray on the web isn't a crash; it's an answer.
  • Zero-leak bundles. Plugin instances live at subpath exports (@moku-labs/system/store, …); the root exports only createApp, createPlugin, ok, err, and types. A store-only consumer carries zero bytes of tray/notify/clipboard/deep-link code.
  • Not a Tauri wrapper. @tauri-apps/* packages are optional peer dependencies, dynamically imported only inside the Tauri providers. Pure-web consumers never install them — and never pay for them.
  • Every exposed method genuinely works, or has a documented typed absence, on both providers. No method that silently no-ops on one side.

Install

bun add @moku-labs/system

Building the native shell too? Add the Tauri plugins the capabilities you compose need:

bun add @tauri-apps/api @tauri-apps/plugin-store @tauri-apps/plugin-notification \
        @tauri-apps/plugin-clipboard-manager @tauri-apps/plugin-deep-link

[!NOTE] Status: 0.x — early. All @tauri-apps/* packages are optional peer dependencies — they are only loaded inside the Tauri providers, via dynamic import, when the native shell is actually detected. Pure-web consumers skip them entirely.

Quick start

import { createApp } from "@moku-labs/system";
import { storePlugin } from "@moku-labs/system/store";

const system = createApp({
  plugins: [storePlugin],
  pluginConfigs: { store: { name: "my-app" } }
});

await system.start();

const result = await system.store.get<number>("count");
if (result.ok) {
  console.log(result.value ?? 0, `(from the ${result.provider} provider)`);
} else if (result.reason === "unsupported") {
  // hide the feature — this environment will never support it
} else {
  console.warn(result.reason, result.message);
}

await system.stop();

[!IMPORTANT] Plugin instances are imported from subpaths@moku-labs/system/store, /tray, /notify, /clipboard, /deep-link. The root entry exports createApp, createPlugin, ok, err, and types only. Why: zero-leak bundles — a root barrel re-exporting instances leaked ~2 KB gzipped of unimported capability code into every consumer (measured); with subpaths, a store-only app carries none of the other capabilities.

How it works

flowchart LR
  C["Your island code<br/>app.store.get(&quot;count&quot;)"] --> A["createApp<br/>(Layer 3 composition)"]
  A --> P["capability plugins<br/>store · tray · notify · clipboard · deepLink"]
  P --> R["runtime seam<br/>ctx.runtime — detected once"]
  R --> W["web provider<br/>(fallback)"]
  R --> T["Tauri provider<br/>(native shell)"]
  W --> S["SystemResult&lt;T&gt;<br/>typed outcome"]
  T --> S
  classDef u fill:#0b7285,stroke:#08525f,color:#fff;
  classDef m fill:#1864ab,stroke:#0d3d6e,color:#fff;
  class C,S u
  class A,P,R,W,T m

The runtime core plugin (registered automatically, alongside logPlugin + envPlugin from @moku-labs/common) detects the shell once — kind: "tauri" when the Tauri 2 marker is present on globalThis, "web" otherwise — and injects ctx.runtime ({ kind, platform }) on every plugin's context. Each capability plugin resolves its provider from that detection at app.start(), fire-and-forget: resolution failures fold into the result of the next call, never into a startup throw. Detection happens once, inside the framework. Islands never branch on the runtime.

The SystemResult contract

Every capability method returns SystemResult<T> — a discriminated union you narrow with result.ok:

type SystemOk<T> = { ok: true; value: T; provider: "tauri" | "web" };
type SystemErr = { ok: false; provider: "tauri" | "web"; reason: SystemErrorReason; message?: string };
type SystemResult<T> = SystemOk<T> | SystemErr;

| reason | Meaning | What to do | |---|---|---| | unsupported | The capability does not exist here — permanently (tray on web, tray on Tauri iOS/Android, clipboard in an insecure context). | Hide the feature. | | denied | The user or platform unambiguously refused permission (notification permission not granted, clipboard NotAllowedError). | Explain, or call requestPermission() deliberately. | | unavailable | The environment can't deliver right now — provider failed to resolve, app not started, Safari private-mode storage probe failed. | Retry later or degrade gracefully. | | error | The provider threw during the operation; the raw message is preserved in message. | Log it (ctx.log already did) and recover. |

Environmental failure is data; programmer errors still throw normally (e.g. an empty store.name fails fast at createApp with a TypeError). Thrown provider errors are never mapped to denied — Tauri ACL throws are ambiguous, so denied is reserved for unambiguous returned permission signals.

Plugins

Compose only what you need — each plugin mounts its API at app.<name>:

| Plugin | Import from | Config (pluginConfigs key) | Key API | Events | |---|---|---|---|---| | storePlugin | @moku-labs/system/store | store: { name } (default "moku-system") | get / set / delete / keys / clear — JSON-safe key-value persistence (Tauri store file with awaited save(); IndexedDB via idb-keyval on web) | — | | trayPlugin | @moku-labs/system/tray | tray: { id } (default "moku-system") | setMenu / setTooltip / setIcon / destroy — desktop tray icon, created lazily on first mutating call | — | | notifyPlugin | @moku-labs/system/notify | — (no config) | show / requestPermission / isPermissionGranted — explicit permission flow; show() never auto-prompts | — | | clipboardPlugin | @moku-labs/system/clipboard | — (no config) | readText / writeText — text only; feature-probed, NotAllowedError"denied" | — | | deepLinkPlugin | @moku-labs/system/deep-link | deepLink: { schemes } (default [] = all) | getCurrent / onOpen — launch URL + runtime deliveries, deduped | deepLink:open | | runtime (core — auto-registered) | — | runtime: { forceKind, forcePlatform } (default null = auto-detect) | ctx.runtime.kind / ctx.runtime.platform — the single override point for the whole seam | — |

[!NOTE] tray is desktop-only by nature: the web provider and the Tauri mobile (iOS/Android) branch both answer every method with err("unsupported") — same contract, no special-casing.

Usage

Composing multiple capabilities

import { createApp } from "@moku-labs/system";
import { deepLinkPlugin } from "@moku-labs/system/deep-link";
import { notifyPlugin } from "@moku-labs/system/notify";
import { storePlugin } from "@moku-labs/system/store";

const system = createApp({
  plugins: [storePlugin, notifyPlugin, deepLinkPlugin],
  pluginConfigs: {
    store: { name: "my-app" },
    deepLink: { schemes: ["myapp"] }
    // notify and clipboard take no config — nothing to put here
  }
});

await system.start();

// Explicit permission flow — show() never auto-prompts.
const granted = await system.notify.isPermissionGranted();
if (granted.ok && !granted.value) {
  await system.notify.requestPermission();
}
await system.notify.show({ title: "Done", body: "Export finished." });

// Deep links: launch URL + runtime deliveries.
const launch = await system.deepLink.getCurrent();
const unsubscribe = system.deepLink.onOpen(({ url }) => route(url));

Forcing the runtime (tests, storybooks)

The runtime core plugin detects the shell from the environment — "tauri" when the __TAURI_INTERNALS__ marker exists on globalThis, "web" otherwise, and the platform from the user-agent. Consumer tests make provider decisions deterministic by stubbing that environment before the app starts (core-plugin config is fixed at the framework layer and not overridable from createApp):

// Force "tauri" detection: define the shell marker before start() — and pair it with
// mocks of the @tauri-apps/* modules your capabilities load (see each plugin README).
vi.stubGlobal("__TAURI_INTERNALS__", {});

// Force "web" detection: simply run without the marker (the default in vitest/Node).
const app = createApp({
  plugins: [storePlugin],
  pluginConfigs: { store: { name: "test-db" } }
});

[!TIP] Extending the framework. createPlugin defines a consumer plugin bound to this framework's types — its ctx carries ctx.runtime, ctx.log, and ctx.env:

import { createApp, createPlugin } from "@moku-labs/system";

const myPlugin = createPlugin("my", {
  api: ctx => ({ ping: () => ctx.runtime.kind })
});

const app = createApp({ plugins: [myPlugin] });

Development

bun run build              # Build with tsdown (root + 5 subpath entries)
bun run test               # All tests (vitest)
bun run test:unit          # Unit tests only
bun run test:integration   # Integration tests only
bun run test:coverage      # Coverage (90% threshold)
bun run lint               # Biome check + ESLint
bun run lint:fix           # Auto-fix lint issues
bun run format             # Format with Biome
bun run validate           # publint + arethetypeswrong

Built test-first. Plugin tests are colocated (src/plugins/<name>/__tests__/unit/ and __tests__/integration/); root tests/ holds framework-level integration only. Providers are exercised through test doubles — the web store provider runs against fake-indexeddb.

Requirements

  • Node >= 24 and Bun >= 1.3.14 — use bun exclusively (never npm/yarn/pnpm).
  • TypeScript in strict mode, with exactOptionalPropertyTypes and noUncheckedIndexedAccess.
  • @moku-labs/core — the micro-kernel this framework is built on (bundled dependency).
  • @tauri-apps/* — optional peers, only in the native shell (see Install).

Docs

License

MIT © moku-labs