@basilica-digital/maypop-sdk

中文文档
1.5.0发布于 2026/10/29Apache-2.0TypeScriptES Module零依赖构建来源已验证近 30 天下载 5973

The browser SDK for apps running on Maypop.

原始使用文档
文档目录13 节
  1. Install
  2. React
  3. Local development hosts
  4. Vite
  5. Rsbuild
  6. Next.js
  7. Authenticated development
  8. Local identities and audiences
  9. Mock integrations and host actions
  10. Hosted script compatibility
  11. Backend artifacts
  12. Development
  13. Release

maypop-sdk

The framework-neutral browser SDK for apps running on Maypop. It exposes the same object and capabilities as the hosted /sdk/v1.js script: identity, KV, Drive, AI, integrations, multiplayer, notifications, and the other APIs in the typed Maypop contract.

Install

pnpm add @basilica-digital/maypop-sdk

Import the SDK from browser code and wait for the Maypop host before using a capability:

import { maypop } from "@basilica-digital/maypop-sdk";

await maypop.ready();
const todos = await maypop.kv.list({ prefix: "todo/" });

The default and named exports are the exact same object as window.maypop, so framework code and scripts can interoperate without adapters:

import maypop, { type Maypop } from "@basilica-digital/maypop-sdk";

function currentUser(sdk: Maypop = maypop) {
  return sdk.user;
}

The module is safe to import while a framework renders on the server. Accessing the SDK there still throws because capabilities belong to the browser-hosted app session. Call getMaypop() from browser-only code when an SSR framework needs to defer access explicitly.

React

React apps can subscribe to Maypop state without manually coordinating the host handshake or effect cleanup:

import {
  useMaypopKV,
  useMaypopMode,
  useMaypopSession,
} from "@basilica-digital/maypop-sdk/react";

export function Counter() {
  const session = useMaypopSession();
  const mode = useMaypopMode();
  const count = useMaypopKV("counter", 0);

  if (session.status === "connecting") return <p>Connecting…</p>;
  if (session.status === "error") return <p>{session.error.message}</p>;

  return (
    <button
      disabled={mode === "read-only" || count.isMutating}
      onClick={() => count.setValue(count.value + 1)}
    >
      {count.value}
    </button>
  );
}

The hooks use the hosted SDK automatically. MaypopProvider is only needed to inject another client in a test or future local sandbox host:

import { MaypopProvider } from "@basilica-digital/maypop-sdk/react";

<MaypopProvider client={sandboxClient}>
  <App />
</MaypopProvider>

Local development hosts

Vite

Add the Maypop plugin to an existing Vite configuration:

import { maypop } from "@basilica-digital/maypop-sdk/vite";
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [maypop()],
});

Rsbuild

Add the equivalent plugin to an Rsbuild configuration:

import { defineConfig } from "@rsbuild/core";
import { maypop } from "@basilica-digital/maypop-sdk/rsbuild";

export default defineConfig({
  plugins: [maypop()],
});

Next.js

Wrap a Next.js configuration. The wrapper adds its sandbox proxy only to next dev; builds and production servers keep the original configuration:

import { withMaypop } from "@basilica-digital/maypop-sdk/next";

export default withMaypop({
  output: "export",
});

The framework's normal development command then serves its URL as a Maypop host with the application inside it, including when a routed application opens or refreshes a deep URL. The app uses the production SDK handshake, iframe permissions, and API shapes. Shared KV state persists to .maypop/local/kv.json, while Drive metadata and bytes persist under .maypop/local/drive/.

The Next.js binding also adds the machine's active network addresses to allowedDevOrigins, so opening the development server from another device on the LAN loads and hydrates its client scripts. Any configured entries are preserved.

Identity, members, KV, Drive, mock MCP integrations, share-card previews, and a notification outbox are available locally. Their capability scopes are reported through maypop.user.scopes; APIs that need another capability fail with maypop/unsupported when they reach the local host. maypop.apps.open() and group-settings navigation remain unavailable because they require the Maypop product shell rather than an app API.

maypop.notify() is captured by default rather than delivered. Open the Maypop badge in the development host, or visit /_maypop/notifications, to inspect the requested and resolved recipients, title, body, and deep link. Captured calls persist in .maypop/local/notifications.json.

Authenticated development

Create .maypop/local/dev.json to opt this machine into authenticated capabilities. Git ignores it with the rest of .maypop/local/: it selects a developer account and can enable access to real app data or billable AI calls.

Hybrid mode keeps KV and Drive local while forwarding an explicit set of read-only or non-data capabilities through the account authenticated by maypop auth:

{
  "mode": "hybrid",
  "profile": "dev",
  "remoteCapabilities": ["ai", "members", "link", "mcp", "multiplayer"],
  "notifications": "inspect"
}

ai includes chat completions, streaming, decisions (typed classification, routing, gating, and scoring on TypeSafe's Jev model), images, video, audio, transcription, and maypop.agent (the development host serves its lazy browser chunk). These calls use the selected account's real allowance and can consume credits. members reads the real app roster, link enables server-side URL unfurling, mcp exposes the app's real linked MCP servers and tools, and multiplayer uses the real rendezvous API while loading the Iroh JS/Wasm runtime locally. KV and Drive remain local, and notifications remain in the inspector. Connect a server with maypop mcp connect, then run maypop mcp link in the app repository before starting the development server. A hybrid configuration cannot combine the real mcp capability with .maypop/local/mcp.json fixtures.

Connected mode skips local KV/Drive initialization and sends the entire app API surface to the real app:

{
  "mode": "connected",
  "profile": "dev",
  "notifications": "inspect"
}

The project must already be connected by maypop init, and the selected CLI profile must be authenticated and have access to that app. Omit profile to use the normal CLI selection rules, including MAYPOP_PROFILE and the profile whose API URL matches the repository. The Node development host reads the owner-only profile store written by maypop auth and mints a short-lived, app-scoped session itself. The saved CLI credential and session refresh token are never exposed to application code or written under .maypop/.

Real notification delivery requires connected mode and a second explicit opt-in:

{
  "mode": "connected",
  "notifications": "live"
}

Use "notifications": "disabled" to remove notification permission entirely. The default is "inspect" in every development mode.

Local identities and audiences

Sandbox mode can start as an anonymous, reader, writer, editor, or admin viewer and expose a configurable audience. This exercises the same public identity, mode, scope, members, and sign-in behavior as the hosted SDK:

{
  "mode": "sandbox",
  "viewer": {
    "username": "Visitor",
    "role": "reader",
    "anonymous": true,
    "signInGrantsWrite": true,
    "signedInUsername": "Alice",
    "signedInRole": "writer"
  },
  "members": [
    { "username": "Bob", "role": "editor", "connected": false }
  ],
  "guestCount": 2
}

Calling maypop.signIn() in this fixture upgrades the local session and reloads the app as the configured signed-in viewer. The local API enforces read-only KV, Drive, and notification scopes, so direct requests cannot bypass the browser SDK's permission checks.

Local KV writes validate the production key and value limits. Set "strictStorage": true to additionally enforce a committed .maypop/kv-policy.json during local pulls and pushes. Preset and advanced policies use the same roles, key patterns, and ownership predicates as the platform.

Mock integrations and host actions

Add .maypop/local/mcp.json to exercise MCP discovery, tool wrapping, calls, and agent tools without invoking a real external integration:

{
  "schemaVersion": 1,
  "servers": [
    {
      "id": "search",
      "name": "Fixture search",
      "url": "mock://search",
      "account": "[email protected]",
      "tools": [
        {
          "name": "lookup",
          "description": "Return a fixed search fixture.",
          "inputSchema": {
            "type": "object",
            "properties": { "query": { "type": "string" } }
          },
          "result": {
            "content": [{ "type": "text", "text": "Fixture result" }],
            "structuredContent": { "items": [] }
          }
        }
      ]
    }
  ]
}

maypop.link.to(path) returns a local deep link and maypop.share() opens a host-owned card containing one. Captured notifications with a path expose an Open in local app action in the outbox. The local host opens these the way Maypop does — the app loads at its entry with the path in location.hash and maypop.launchPath — so an app that routes correctly here routes correctly once published. None of this claims that a local link was published or that a captured notification was delivered.

The local bearer token is random for every server run, and a lock prevents two development servers from writing the same data directory. To use a different directory or viewer name:

maypop({
  dataDirectory: ".maypop/alice",
  username: "Alice",
});

The local host is development tooling, not a security boundary. Keep the development server bound to a trusted interface unless the project itself is safe to expose.

What belongs to this machine lives in .maypop/local/: the local identity, dev.json, MCP fixtures, KV and Drive data, captured notifications, and the lock. The development server creates it with its own .gitignore, so it stays out of Git even when the app's .gitignore does not mention it. .maypop/kv-policy.json stays beside it and is committed: the platform reads it from the app's source and applies it with each published version. On its first run, the server moves what older versions wrote directly into .maypop/ into .maypop/local/. It leaves an old .maypop/.lock where it is and no longer reads it; untrack one that was committed with git rm --cached .maypop/.lock.

The lock holds only while the process that wrote it runs. It records that process's PID and start time, so a lock left behind by a server that was killed, or whose sandbox restarted and gave its PID to another process, is taken over. A server that exits without closing still removes its lock.

The bindings only affect framework development servers. Production builds remain ordinary app bundles. maypop init records the matching build adapter in maypop.toml, and maypop publish builds and uploads its static output.

Hosted script compatibility

Existing apps can keep loading the global build:

<script src="https://api.dev.maypop.ai/sdk/v1.js"></script>

Importing @basilica-digital/maypop-sdk installs that same build from the package instead. Both forms use the same host handshake and backend API, and both expose window.maypop. Do not use both forms in one app; the runtime is idempotent, but one is enough.

This package is the guest side of the Maypop protocol. Outside Maypop, maypop.ready() waits for a compatible host. The framework integrations above provide that host protocol without requiring applications to change their SDK imports.

Backend artifacts

The published tarball also contains the generated host scripts, lazy capability chunks, shell document, contracts, and Iroh WebAssembly runtime under dist/. The Maypop backend pins an exact package version and embeds these files into its binary, so a backend build never depends on the SDK repository's moving branch.

The source contract and runtime are available through @basilica-digital/maypop-sdk/source/v1 and @basilica-digital/maypop-sdk/source/runtime for Maypop's own contract tooling. Application code should use the public entry points shown above.

Development

All maintained SDK code lives in src/ as TypeScript. pnpm build compiles the npm entry, hosted global, lazy capability chunks, shell host, injected scripts, service worker, declarations, and backend artifacts into the ignored dist/ directory. Generated JavaScript is never a source of truth and should not be edited directly.

The Iroh runtime lives in iroh/; its generated bindings and WebAssembly are committed under iroh/prebuilt/ so ordinary package builds do not require a Rust/Wasm toolchain. After changing iroh/src, install the wasm32-unknown-unknown target, wasm-bindgen-cli matching the crate's pinned version, and Binaryen's wasm-opt, then run:

just build-iroh

Release

Versions follow SemVer and tags use the matching vX.Y.Z form. Before tagging, update package.json and the lockfile, then run:

pnpm install --frozen-lockfile
pnpm test
pnpm pack

Pushing the matching tag runs the npm publication workflow. The first release must be published by an npm owner; after that, configure this repository as the package's trusted publisher for .github/workflows/release.yml.

版本与发布记录

@basilica-digital/maypop-sdk 共发布 6 个版本,首次发布于 2026/09/21;过去 12 个月发布了 6 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.5.0latest2026/10/299 天前
1.4.02026/10/071 个月前
1.3.02026/09/301 个月前
1.2.02026/09/241 个月前
1.1.02026/09/221 个月前
1.0.02026/09/211 个月前

关于 @basilica-digital/maypop-sdk 的常见问题

@basilica-digital/maypop-sdk 是什么?

The browser SDK for apps running on Maypop.

如何安装 @basilica-digital/maypop-sdk?

在项目目录运行 npm install @basilica-digital/maypop-sdk,或使用 pnpm add / yarn add / bun add。

@basilica-digital/maypop-sdk 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@basilica-digital/maypop-sdk 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@basilica-digital/maypop-sdk 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@basilica-digital/maypop-sdk 可以商用吗?

@basilica-digital/maypop-sdk 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@basilica-digital/maypop-sdk 的下载量有多少?

根据 npm 官方下载统计,@basilica-digital/maypop-sdk 在 2026/10/08 – 2026/11/06 这 30 天内被下载 5,973 次,日均约 199 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@basilica-digital/maypop-sdk 还在维护吗?

最新版本 1.5.0 发布于 2026/10/29(9 天前);至今共发布 6 个版本,其中过去 12 个月发布了 6 个;首次发布于 2026/09/21。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。