Use @worldcoin/idkit when you want React-native ergonomics on top of @worldcoin/idkit-core.
Install
Choose your API
- Widgets: quickest integration, built-in modal and state handling
- Hooks: headless control for custom UI and flow orchestration
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"
onSuccess={async (result) => {
await fetch("/api/verify-proof", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ rp_id: rpContext.rp_id, devPortalPayload: result }),
});
}}
onError={(errorCode) => {
console.error("IDKit error", errorCode);
}}
/>;
import { IDKitSessionWidget, orbLegacy, type RpContext } from "@worldcoin/idkit";
<IDKitSessionWidget
open={open}
onOpenChange={setOpen}
app_id="app_xxxxx"
rp_context={rpContext}
existing_session_id={existingSessionId}
preset={orbLegacy()}
environment="production"
onSuccess={(result) => {
// Save result.session_id for future proveSession flows
console.log(result.session_id);
}}
/>;
existing_session_id switches the widget from create-session mode to prove-session mode.
Headless hooks
useIDKitRequest
import { useIDKitRequest, orbLegacy } from "@worldcoin/idkit";
const flow = useIDKitRequest({
app_id: "app_xxxxx",
action: "my-action",
rp_context,
allow_legacy_proofs: false,
preset: orbLegacy({ signal: "user-123" }),
polling: {
interval: 2_000,
timeout: 120_000,
},
});
<button onClick={flow.open} disabled={flow.isAwaitingUserConfirmation}>
Verify
</button>;
useIDKitSession
import { useIDKitSession, orbLegacy } from "@worldcoin/idkit";
const sessionFlow = useIDKitSession({
app_id: "app_xxxxx",
rp_context,
preset: orbLegacy(),
existing_session_id: sessionId,
polling: {
interval: 2_000,
timeout: 120_000,
},
});
if (sessionFlow.isSuccess && sessionFlow.result) {
console.log("session", sessionFlow.result.session_id);
}
Shared hook result fields:
open()
reset()
isAwaitingUserConnection
isAwaitingUserConfirmation
isSuccess
isError
connectorURI
result
errorCode
Presets and constraints
React hooks/widgets currently take preset directly in config.
constraints are not currently exposed through React hook/widget config.
If you need explicit any/all/CredentialRequest trees today, build the flow with
@worldcoin/idkit-core and use your own React UI.
Use presets mainly for migration from older IDKit versions. They are designed
to keep compatibility across World ID 4.0 and World ID 3.0 (legacy) flows.
Localization and UX notes
- Widgets support
language="en" | "es" | "th"
- Widgets default to
autoClose={true} after success
- Host callback exceptions are swallowed to keep the widget state machine stable
Backend utilities
For RP signature generation in React/Next.js apps, use the pure JS subpath:
import { signRequest } from "@worldcoin/idkit/signing";
Related pages