Skip to main content
Use @worldcoin/idkit when you want React-native ergonomics on top of @worldcoin/idkit-core.

Install

npm i @worldcoin/idkit

Choose your API

  • Widgets: quickest integration, built-in modal and state handling
  • Hooks: headless control for custom UI and flow orchestration

Controlled widgets

Request widget

import { IDKitRequestWidget, orbLegacy, type RpContext } from "@worldcoin/idkit";

const rpContext: RpContext = {
  rp_id: "rp_xxxxx",
  nonce: "0x...",
  created_at: 1735689600,
  expires_at: 1735689900,
  signature: "0x...",
};

<IDKitRequestWidget
  open={open}
  onOpenChange={setOpen}
  app_id="app_xxxxx"
  action="my-action"
  rp_context={rpContext}
  allow_legacy_proofs={true}
  preset={orbLegacy({ signal: "user-123" })}
  environment="production"
  handleVerify={async (result) => {
    const response = await fetch("/api/verify-proof", {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ rp_id: rpContext.rp_id, idkitResponse: result }),
    });

    if (!response.ok) {
      throw new Error("Backend verification failed");
    }
  }}
  onSuccess={() => {
    // Called after `handleVerify` resolves (or immediately if omitted).
    // Update your app state/UI here.
  }}
  onError={(errorCode) => {
    console.error("IDKit error", errorCode);
  }}
/>;

Widget callbacks

  • onSuccess is required for IDKitRequestWidget and IDKitSessionWidget.
  • handleVerify is optional and only available on widgets. Use it to verify the proof in your backend before success is emitted.
  • If handleVerify throws/rejects, the widget enters an error state, emits onError("failed_by_host_app"), and does not call onSuccess.
  • onError is optional.

Headless hooks

useIDKitRequest

import { useIDKitRequest, orbLegacy } from "@worldcoin/idkit";

const flow = useIDKitRequest({
  app_id: "app_xxxxx",
  action: "my-action",
  rp_context,
  allow_legacy_proofs: true,
  preset: orbLegacy({ signal: "user-123" }),
  polling: {
    interval: 2_000,
    timeout: 120_000,
  },
});

<button onClick={flow.open} disabled={flow.isAwaitingUserConfirmation}>
  Verify
</button>;
Hook result fields:
  • open()
  • reset()
  • isAwaitingUserConnection
  • isAwaitingUserConfirmation
  • isSuccess
  • isError
  • connectorURI
  • result
  • errorCode

Presets

React hooks/widgets take preset directly in config.

Localization and UX notes

  • Widgets support language="en" | "es" | "th"
  • Widgets default to autoClose={true} after success

Backend utilities

For RP signature generation in React/Next.js apps, use the pure JS subpath:
import { signRequest } from "@worldcoin/idkit/signing";