IDKit is open source and accepts contributions! Head over to GitHub and submit a pull request.
There are three packages available in the IDKit Monorepo: @worldcoin/idkit, @worldcoin/idkit-standalone, and @worldcoin/idkit-core. The @worldcoin/idkit package is the main package that should be used with the React JS framework. The @worldcoin/idkit-standalone package is a standalone package that can be used in vanilla JavaScript applications. The @worldcoin/idkit-core package is a core functionality package that is used by the other two packages, and should be used only when creating a new IDKit package.

IDKit (React)

The @worldcoin/idkit package is the main package that should be used with the React framework or any other framework that supports React components, such as Next.JS.

Components

IDKitWidget

The IDKitWidget component is the main component that renders the World ID widget. It should be mounted in your React app and passed the relevant parameters. Accepts a function as a child that receives an open function to open the widget.
import { IDKitWidget } from '@worldcoin/idkit'

<IDKitWidget
	app_id="app_GBkZ1KlVUdFTjeMXKlVUdFT" // obtained from the Developer Portal
	action="vote_1" // this is your action name from the Developer Portal
	signal="user_value" // any arbitrary value the user is committing to, e.g. a vote
	onSuccess={onSuccess}
	verification_level="device" // minimum verification level accepted, defaults to "orb"
>
	{({ open }) => <button onClick={open}>Verify with World ID</button>}
</IDKitWidget>

Parameters

The following parameters can be passed as props to the IDKitWidget component:

Hooks

useIDKit

The useIDKit hook allows you to programmatically open the IDKit widget without mounting any buttons on screen. Note that you still need to mount the component for this to work.
import { IDKitWidget, useIDKit } from '@worldcoin/idkit'

const { open, setOpen } = useIDKit()

useEffect(() => {
	setOpen(true)
}, [])

return (
	<div>
		<IDKitWidget app_id="..." action="..." />
	</div>
)

useSession

The useSession hook provides a React-friendly way to handle World ID verification sessions with full control over the UI. It automatically manages session creation and polling for verification updates.
import { useSession, VerificationState } from '@worldcoin/idkit'

const { status, sessionURI, result, errorCode, reset } = useSession({
	app_id: 'app_staging_12345',
	action: 'login',
	signal: 'user_123',
})

if (status === VerificationState.WaitingForConnection && sessionURI) {
	return <QRCodeSVG value={sessionURI} />
}

if (status === VerificationState.Confirmed && result) {
	return <div>Verification successful!</div>
}
Parameters: Returns (UseSessionResult): Verification States:

Functions

verifyCloudProof

The verifyCloudProof function is used to verify a proof returned from the user’s identity wallet (e.g. World App) against the Developer Portal API. This function is useful for verifying proofs on the server side.
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
	const { proof, action, signal } = req.body
    const app_id = process.env.APP_ID
	const response = (await verifyCloudProof(proof, app_id, action, signal)) as IVerifyResponse
	res.status(response.success ? 200 : 400).json(response)
}

Types

ISuccessResult

{
	"merkle_root": "0x1f38b57f3bdf96f05ea62fa68814871bf0ca8ce4dbe073d8497d5a6b0a53e5e0",
	"nullifier_hash": "0x0339861e70a9bdb6b01a88c7534a3332db915d3d06511b79a5724221a6958fbe",
	"proof": "0x063942fd7ea1616f17787d2e3374c1826ebcd2d41d2394...",
	"verification_level": "orb"
}

IErrorState

{
	"code": "already_signed",
	"detail": "User has previously signed and submitted proof for this action."
}

IVerifyResult

{
    "success": false,
	"code": "invalid_proof",
	"detail": "The provided proof is invalid and it cannot be verified. Please check all inputs and try again.",
    "attribute": null,
}

Error Handling

An error in IDKit will generally be returned as the input to the onError callback. IDKit will display an error to the user and call the onError callback with an IErrorState object when the modal is closed.
View the Errors Reference for assistance when troubleshooting.

IDKit Standalone

The @worldcoin/idkit-standalone package is intended for vanilla JS applications. It is a standalone package that acts as a wrapper around the @worldcoin/idkit package.

Methods

The .init() and .update() methods take the same parameters as the React package’s IDKitWidget component. See above for more details.

.init()

The .init() method is the main initialization method used for vanilla JS apps. It should be called to start up IDKit and configure the widget.
import { IDKit } from '@worldcoin/idkit-standalone'

const onSuccess = (result) => {
	// handle success
}

IDKit.init({
	app_id: 'app_lshSNnaJfdt6Sohu6YAA',
	action: 'my_action',
	onSuccess: onSuccess,
})

.update()

The .update() method reinitializes the widget with new parameters. It can only be called after the .init() method.
IDKit.update({
	app_id: 'app_lshSNnaJfdt6Sohu6YAA',
	action: 'my_new_action',
	onSuccess: onSuccess,
})

.open()

The .open() method is used to open the widget. It can only be called after the .init() method, typically in response to a button click. This method returns a Promise object that will resolve when the onSuccess callback is called, or reject when the onError callback is called.
IDKit.open()

Session API

IDKitSession

The IDKitSession object provides a session-based approach to World ID verification with full control over the verification flow. Unlike the widget approach, this gives you complete control over UI and state management.
import { IDKitSession, VerificationState } from '@worldcoin/idkit'

// Create a session
await IDKitSession.create({
	app_id: 'app_staging_12345',
	action: 'login',
	signal: 'user_123',
})

// Get QR code URI
const sessionURI = IDKitSession.getURI()

// Poll for updates
const status = await IDKitSession.pollStatus()
if (status.state === VerificationState.Confirmed) {
	console.log('Verification successful!', status.result) // Verify the proof in your backend
}

// Clean up
IDKitSession.destroy()

IDKitSession.create(config)

Creates a new World ID verification session. If a session already exists, it will be destroyed and replaced. Returns: Promise that resolves when session is created

IDKitSession.getURI()

Gets the current session URI for QR code generation. Returns: string | null - The session URI or null if no active session

IDKitSession.pollStatus()

Polls for verification updates and returns current session status. Returns: Promise with SessionStatus object

IDKitSession.destroy()

Destroys the current session and cleans up resources. Returns: void

IDKitSession.isActive

Property that returns whether there’s an active session. Returns: boolean
if (IDKitSession.isActive) {
	const status = await IDKitSession.pollStatus()
}

Advanced configuration

This section outlines advanced configuration options that may be unstable or subject to change. These options are passed as a JSON object to the advanced prop of the IDKitWidget component.

Self-Hosted Applications

Self-hosted applications bypass the Worldcoin Developer Portal entirely. The proof returned can not be verified by the Developer Portal API. Instead, you must verify the proof on-chain or with a custom prover service. When using self-hosted mode, no app_id is required, and any value passed to IDKit will be ignored. The action you set must have sufficient uniqueness to avoid collisions with other applications. We recommend using a prefix that includes your application name, e.g. your_app_name_vote_1.
import { IDKitWidget } from '@worldcoin/idkit'

<IDKitWidget
	// no app_id is set for self-hosted applications
	action="your_app_name_vote_1" // this is your action, set to whatever you'd like
	signal="user_value"
	onSuccess={onSuccess}
	verification_level="orb" // only orb verifications are supported for self-hosted applications
	advanced={{
		self_hosted: true // enable the self-hosted mode
	}}
>
	{({ open }) => <button onClick={open}>Verify with World ID</button>}
</IDKitWidget>