Vouch
Quickstart

Expo / React Native

Add Vouch with the Expo config plugin. The module wraps the native iOS and Android SDKs.

Package not yet published

The module lives in the repository under sdks/react-native and can be installed from a local path or Git today. An npm release follows.

@vouch/react-native is built on the Expo Modules API, so it works in Expo projects and in bare React Native. It is a thin bridge over the native SDKs: matching, the offline event queue, the device identifier and exactly-once delivery run in Swift and Kotlin.

Install

npx expo install @vouch/react-native

Configure the plugin

The config plugin adds the Associated Domains entitlement on iOS and the verified intent filter plus singleTask launch mode on Android at prebuild, so you never hand-edit native projects:

{
  "expo": {
    "plugins": [
      ["@vouch/react-native", { "domains": ["yourapp.vouch.dev"] }]
    ]
  }
}

Run npx expo prebuild to apply it. In a bare React Native project, add the entitlement and the intent filter yourself, as the iOS and Android quickstarts show.

Your publishable key and app id are in the dashboard under Settings → API keys and Apps.

import { Vouch, useVouchLink } from "@vouch/react-native";

Vouch.configure({
  publishableKey: "pk_test_…",
  appId: "app_…",
  environment: "test",
  options: { linkHosts: ["yourapp.vouch.dev"] },
});

export default function Root() {
  const router = useRouter();

  useVouchLink((link) => {
    // Exactly once per link, cold or warm start.
    router.push({ pathname: link.destination, params: link.params });
  });

  useEffect(() => {
    Vouch.setReady();   // your navigator exists; held links arrive now
  }, []);

  return <Slot />;
}

Outside React, Vouch.addLinkListener(handler) returns a subscription you remove yourself.

A link matched to an install arrives with isDeferred: true. matchType is one of install_referrer, clipboard, session, probabilistic, ambiguous or none; the first three were carried by a token and are deterministic. Ambiguous fingerprints deliver nothing rather than guessing.

const pending = await Vouch.pendingLink();   // peek without consuming
if (pending) onboarding.preselect(pending.params.ref);
Vouch.identify("user_123");
Vouch.track("checkout_completed", { plan: "pro" });

const link = await Vouch.createLink({ destination: "/invite", params: { ref: userId } });
await Share.share({ message: link.url });

Events queue on device and are delivered in order with server-side deduplication, so calls are safe offline.

Referrals and device security

Planned API, not yet shipped

The calls below are the agreed shape of the SDK additions for Referrals and device security. They are not in a released SDK yet. The server endpoints they call are live, so you can drive both modules over HTTP today using the routes in those sections.

// A personal invite link and code for the signed-in user.
const invite = await Vouch.referrals.link();
await Share.share({ message: invite.url });

// Someone typing a code instead of following a link.
await Vouch.referrals.redeem("W3ZYEPD8");

// Attestation runs automatically; this is the manual trigger.
const verdict = await Vouch.security.attest();

Verify

Run the example app in sdks/react-native/example, then use the dashboard's verification step with a physical device. From an Android emulator, set options: { apiBaseUrl: "http://10.0.2.2:8787" } to reach a local server.

On this page