liveface
v1.2.0
Published
React Native (Expo) SDK for LivFace — drop-in biometric liveness detection and ID document verification using challenge-response camera analysis.
Maintainers
Readme
liveface
React Native (Expo) SDK for LivFace — challenge-response biometric liveness detection and ID document verification.
- Detects real humans vs photos, video replays, and deepfakes
- 7 randomised challenge types per session (Blink, Smile, Turn Left/Right, Open Mouth, Look Down, Raise Eyebrows)
- Optional ID document matching — compare a live face against a passport/ID photo
- Drop-in
<LivenessView>component or low-leveluseLivenesshook for custom UIs - Handles camera permissions, frame capture, progress display, and result overlay automatically
Requirements
- Expo SDK 50+
expo-camera≥ 14- React Native ≥ 0.73
- A LivFace API account and API key → livface.com
Installation
npx expo install expo-camera
npm install livefaceAdd camera permission to your app.json:
{
"expo": {
"plugins": [
["expo-camera", { "cameraPermission": "Allow $(PRODUCT_NAME) to verify your identity." }]
]
}
}Quick start
1. Create a session from your backend
Never call this from the client — your API key must stay on the server.
// Your backend (Node.js, Python, etc.)
const res = await fetch('https://api.yourdomain.com/v1/sessions', {
method: 'POST',
headers: {
'x-api-key': process.env.LIVEFACE_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({ challenge_count: 5 }),
})
const { session_id } = await res.json()
// Pass session_id to your mobile app2. Drop in <LivenessView>
import { LivenessView } from 'liveface'
export function VerifyScreen({ route, navigation }) {
const { sessionId } = route.params
return (
<LivenessView
apiUrl="https://api.yourdomain.com"
sessionId={sessionId}
onComplete={(result) => {
if (result.passed) {
navigation.replace('Success', { score: result.score })
} else {
navigation.replace('Failed', { reason: result.reason })
}
}}
/>
)
}That's it. The component handles everything: permission requests, camera preview, challenge instructions, progress dots, and the pass/fail overlay.
ID document verification
Pass a base64 JPEG of the ID/passport photo as idImageB64. LivFace will extract the face from the document and compare it against the live capture on the final frame.
<LivenessView
apiUrl="https://api.yourdomain.com"
sessionId={sessionId}
idImageB64={idPhotoBase64} // base64 JPEG, no data-URI prefix
onComplete={(result) => {
console.log(result.passed) // overall result
console.log(result.idVerified) // ID face matched live face
console.log(result.idMatchScore) // 0.0 – 1.0 similarity score
console.log(result.livenessVerified) // passed all challenges
}}
/>Custom UI with useLiveness
Use the hook directly when you need full control over the camera view or UI layout.
import { useRef } from 'react'
import { CameraView } from 'expo-camera'
import { useLiveness } from 'liveface'
export function CustomVerifyScreen({ sessionId }) {
const { cameraRef, phase, status, progressCount, progressTotal, start, reset } =
useLiveness({
apiUrl: 'https://api.yourdomain.com',
sessionId,
frameIntervalMs: 800,
onComplete: (result) => console.log(result),
onError: (err) => console.error(err),
})
return (
<>
<CameraView ref={cameraRef} facing="front" style={{ flex: 1 }} />
<Text>{status}</Text>
<Text>{progressCount} / {progressTotal}</Text>
{phase === 'idle' && <Button title="Start" onPress={start} />}
{phase === 'failed' && <Button title="Retry" onPress={reset} />}
</>
)
}Low-level client
For fully custom camera implementations (non-Expo, custom frame capture, etc.):
import { LivenessClient } from 'liveface'
const client = new LivenessClient('https://api.yourdomain.com')
// Optional: upload ID photo first
await client.uploadId(sessionId, idImageBase64)
// Drive the session with a frame-capture callback
const result = await client.run(
async () => {
const photo = await camera.takePictureAsync({ base64: true, quality: 0.6 })
return photo.base64
},
{
sessionId,
frameIntervalMs: 1000,
onStatus: (msg) => console.log(msg),
onProgress: (done, total, challenge) => console.log(done, '/', total, challenge),
},
)
console.log(result.passed, result.score, result.idMatchScore)LivenessResult
interface LivenessResult {
passed: boolean // overall pass/fail
sessionId: string
score?: number // liveness confidence 0.0 – 1.0
livenessVerified?: boolean
idVerified?: boolean // ID face matched (only if idImageB64 was provided)
idMatchScore?: number // face similarity 0.0 – 1.0
reason?: string // failure reason: 'spoof_detected' | 'session_expired' | etc.
}License
MIT
