Skip to content

React Integration

This guide walks you through integrating Circadify into a React application using the official React bindings.

The @circadify/react package provides React components and hooks. It requires @circadify/sdk as a peer dependency, so install both:

Terminal window
npm install @circadify/sdk @circadify/react

Wrap your application (or the relevant subtree) with the CircadifyProvider. This initializes the SDK and makes it available to all child components via React context.

import { CircadifyProvider } from '@circadify/react';
function App() {
return (
<CircadifyProvider apiKey="ck_test_your_key_here" environment="sandbox">
<YourApp />
</CircadifyProvider>
);
}
PropTypeDefaultDescription
apiKeystringYour Circadify API key (ck_test_* or ck_live_*). Required.
environment'sandbox' | 'production''production'API environment. Use sandbox during development.
onProgress(progress: ProgressEvent) => voidGlobal callback for scan progress updates.
onQualityWarning(warning: QualityWarning) => voidCalled when lighting, movement, or face positioning issues are detected.
onDeviceOnlybooleantrueRestrict processing to on-device only.

The CircadifyScan component renders a complete scanning interface with a camera feed, face guide overlay, progress indicator, and quality warnings. It handles the full session lifecycle automatically.

import { CircadifyScan } from '@circadify/react';
function ScanPage() {
const handleResult = (result) => {
console.log('Heart Rate:', result.heartRate);
console.log('Confidence:', result.confidence);
};
return (
<CircadifyScan
type="standard"
onResult={handleResult}
onError={(error) => console.error(error)}
/>
);
}
PropTypeDefaultDescription
type'standard''standard'The scan session type.
onResult(result: VitalSignsResult) => voidCalled when a scan completes successfully.
onError(error: CircadifyError) => voidCalled when a scan fails.
onProgress(progress: ProgressEvent) => voidCalled during scan with progress updates.
demographics{ age?: number; sex?: 'M' | 'F' }Optional demographics to improve accuracy.
autoStartbooleanfalseStart scanning immediately when the component mounts.
showFeedbackbooleantrueDisplay quality feedback messages (lighting, movement).
classNamestringCSS class applied to the container element.
styleReact.CSSPropertiesInline styles for the container element.

The onResult callback receives a VitalSignsResult object:

function ScanPage() {
const [vitals, setVitals] = useState(null);
return (
<>
<CircadifyScan
type="standard"
demographics={{ age: 35, sex: 'M' }}
onResult={(result) => setVitals(result)}
onError={(error) => alert(error.message)}
/>
{vitals && (
<div>
<p>Heart Rate: {vitals.heartRate} BPM</p>
<p>SpO2: {vitals.spo2}%</p>
<p>Confidence: {(vitals.confidence * 100).toFixed(0)}%</p>
</div>
)}
</>
);
}

For more control over the scanning lifecycle, use the SDK hooks directly. This is useful when you need a custom UI or want to integrate scanning into an existing component.

Returns the underlying CircadifySDK instance from the nearest CircadifyProvider. Use this for direct SDK access.

import { useCircadify } from '@circadify/react';
function DebugPanel() {
const sdk = useCircadify();
// Access sdk.measureVitals(), sdk.destroy(), sdk.on(), etc.
}

Manages a scan session with start/stop controls and reactive state. Returns the session state, control functions, and result data.

import { useCircadify, useSession } from '@circadify/react';
function CustomScan() {
const client = useCircadify();
const { session, start, stop, result, error, progress, isScanning } = useSession({
type: 'standard',
});
return (
<div>
<button onClick={start} disabled={isScanning}>Start Scan</button>
<button onClick={stop} disabled={!isScanning}>Stop</button>
{isScanning && <p>Progress: {Math.round(progress * 100)}%</p>}
{error && <p>Error: {error.message}</p>}
{result && <pre>{JSON.stringify(result, null, 2)}</pre>}
</div>
);
}

Return values:

PropertyTypeDescription
sessionSession | nullThe active session object, or null if not started.
start() => Promise<void>Start a new scan session.
stop() => Promise<void>Stop the active session.
resultVitalSignsResult | nullThe scan result once complete.
errorCircadifyError | nullThe error if the session failed.
progressnumberProgress value from 0 to 1.
isScanningbooleanWhether a scan is currently in progress.

You can pass an AbortController signal through the hook to allow cancellation:

function CancellableScan() {
const controllerRef = useRef(null);
const { start, stop, result } = useSession({ type: 'standard' });
const handleStart = () => {
controllerRef.current = new AbortController();
start({ signal: controllerRef.current.signal });
};
const handleCancel = () => {
controllerRef.current?.abort();
};
return (
<div>
<button onClick={handleStart}>Start</button>
<button onClick={handleCancel}>Cancel</button>
</div>
);
}

The CircadifyProvider automatically calls sdk.destroy() when it unmounts, releasing camera streams, WASM modules, and event listeners. No manual cleanup is required in most cases.

If you need to manually destroy the SDK instance (for example, on logout), use the useCircadify hook:

const sdk = useCircadify();
sdk.destroy();