Skip to content

nBridgeOne bridge between your web app and every host

Type-safe, real-time messaging with Android WebViews, iOS WKWebViews, and iframes — promise-based, validated, observable.

nBridge

Show me code

Define messages once, get typed payloads and responses everywhere — with the validator you already use, or none at all.

ts
import { z } from "zod";
import { createBridge, defineMessage } from "nbridge";

const schemas = {
  getUser: defineMessage({
    type: "getUser",
    payloadSchema: z.object({ id: z.string() }),
    responseSchema: z.object({ name: z.string(), email: z.string() }),
  }),
};

const bridge = createBridge({ schemas });

// Typed + validated at runtime
const user = await bridge.sendWithResponse("getUser", { id: "42" });
console.log(user.name);
ts
import * as v from "valibot";
import { createBridge, defineMessage } from "nbridge";

const schemas = {
  getUser: defineMessage({
    type: "getUser",
    payloadSchema: v.object({ id: v.string() }),
    responseSchema: v.object({ name: v.string(), email: v.string() }),
  }),
};

const bridge = createBridge({ schemas });

const user = await bridge.sendWithResponse("getUser", { id: "42" });
console.log(user.name);
ts
import { createBridge } from "nbridge";

const bridge = createBridge();

// Fire-and-forget
await bridge.send("analytics", { event: "page_view" });

// Request/response, correlated by message id
const user = await bridge.sendWithResponse<
  { id: string },
  { name: string; email: string }
>("getUser", { id: "42" });

// Listen for messages from the host
bridge.on("themeChanged", (payload) => {
  console.log("Native says:", payload);
});

Released under the MIT License.