react-native-mlkit-face-capture
v2.0.0
Published
React Native face capture module with ML Kit face validation, camera preview, and image compression
Maintainers
Readme
react-native-mlkit-face-capture
A React Native face capture module with ML Kit face validation, camera preview (via react-native-vision-camera), and image compression.
Features
- Camera Preview — Front/back camera with torch support using
react-native-vision-camera - Face Validation — ML Kit-powered validation that always runs on every capture, checking:
- Face presence (single face required)
- Face size (minimum 28% of image)
- Face centering (within 14% horizontal / 16% vertical offset)
- Eyes open (>55% probability)
- Head angle (yaw <7°, pitch <8°, roll <8°)
- Landmark geometry (eye-nose symmetry, eye levelness, nose centering)
- Image Compression — Resize and compress via
@bam.tech/react-native-image-resizer - ROI Overlay — Circular ROI with bracket indicators or rectangular frame, controlled by the
roiShapeprop - i18n Ready — All strings overridable via props
Installation
npm install react-native-mlkit-face-capturePeer Dependencies
Install these in your host application:
npm install react-native-vision-camera @react-native-ml-kit/face-detection react-native-fs @bam.tech/react-native-image-resizerFollow each library's native setup instructions (camera permissions, ML Kit configuration, etc.).
Usage
Full Screen Component
import { FaceCaptureScreen } from 'react-native-mlkit-face-capture';
function MyScreen({ navigation }) {
return (
<FaceCaptureScreen
cameraPosition="front"
roiShape="circular"
compressImage={true}
compressionQuality={80}
onCapture={({ uri, base64, uncompressedUri }) => {
console.log('Captured:', uri);
navigation.goBack();
}}
onGoBack={() => navigation.goBack()}
onValidationError={(message) => {
// Show your own alert/toast
}}
onLoading={(isLoading) => {
// Show/hide your own loader
}}
/>
);
}Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| cameraPosition | 'front' \| 'back' | 'front' | Camera to use |
| roiShape | 'circular' \| 'rectangular' | 'circular' | ROI overlay shape — circular shows bracket indicators, rectangular shows a plain frame |
| compressImage | boolean | false | Whether to compress the captured image |
| compressionQuality | number | 100 | Compression quality (1-100) |
| onCapture | function | — | Callback with { uri, base64, uncompressedUri } |
| onGoBack | function | — | Back button handler |
| onValidationError | function | — | Called with error message string; falls back to Alert.alert |
| onLoading | function | — | Called with boolean during validation |
| validations | string[] | all checks | Array of VALIDATION_CHECKS values to enable (see below) |
| strings | object | built-in English | i18n string overrides |
| BackIcon | ReactNode | < text | Custom back icon element |
| styles | object | — | Style overrides keyed by style name (see below). Merged on top of defaults. |
| backgroundStyle | ViewStyle | — | Deprecated — use styles.container instead |
Custom Styles
By default the component renders with no colors — it inherits the system/OS default theme. Pass a styles object to apply your own visual treatment. Each key corresponds to an internal element:
import { FaceCaptureScreen } from 'react-native-mlkit-face-capture';
<FaceCaptureScreen
styles={{
container: { backgroundColor: '#1A1A2E' },
selfieText: { color: '#E0E0E0' },
positionText: { color: '#E0E0E0' },
faceLitText: { color: '#8D8DAA' },
requestingPermissionText: { color: '#E0E0E0' },
captureButton: { borderColor: '#E94560', backgroundColor: '#FAFAFA' },
cameraContainerCircular: { borderColor: '#E94560' },
cameraContainerRectangular: { borderColor: '#E94560' },
torchButton: { borderColor: '#E94560', backgroundColor: '#16213E' },
torchButtonActive: { backgroundColor: '#E94560' },
torchButtonText: { color: '#E0E0E0' },
torchButtonTextActive: { color: '#1A1A2E' },
topLeftBracket: { borderColor: '#E94560' },
bottomLeftBracket: { borderColor: '#E94560' },
bottomRightBracket: { borderColor: '#E94560' },
topRightBracket: { borderColor: '#E94560' },
}}
onCapture={handleCapture}
onGoBack={handleBack}
/>The defaultStyles export contains the layout-only defaults if you want to inspect or spread them:
import { defaultStyles } from 'react-native-mlkit-face-capture';
console.log(Object.keys(defaultStyles)); // all available style keys| Style key | Element |
|-----------|---------|
| container | Root View |
| overlay | Inner layout wrapper |
| backButtonView | Row containing back button + title |
| backButton | Back button pressable |
| selfieText | Title label and back icon fallback text |
| torchButton | Torch toggle button |
| torchButtonTopRight | Torch button positioning |
| torchButtonActive | Torch button when enabled |
| torchButtonText | Torch button label |
| torchButtonTextActive | Torch button label when enabled |
| cameraContainerCircular | Circular camera frame (roiShape="circular") |
| cameraContainerRectangular | Rectangular camera frame (roiShape="rectangular") |
| cameraView | Camera preview itself |
| positionText | "Position your face" label |
| faceLitText | Subtitle hint label |
| textView | Container for position/hint labels |
| captureButton | Shutter button |
| topLeftBracket / bottomLeftBracket / bottomRightBracket / topRightBracket | Corner bracket decorations |
| requestingPermissionText | "Awaiting permission" label |
Using Individual Utilities
import {
useSetupCamera,
CameraPreview,
takePhoto,
validateSelfie,
compressImage,
} from 'react-native-mlkit-face-capture';
// Camera hook
const { device, hasPermission, cameraRef } = useSetupCamera('front');
// Validate a photo
const result = await validateSelfie(photoUri);
if (result.valid) {
console.log('Face detected:', result.face);
}
// Compress an image
const compressedUri = await compressImage(uri, 800, 600, 80);Selecting Validations
By default all checks run. Use the validations prop (or the third argument to validateSelfie) to enable only the checks you need. Face detection (single face present) always runs regardless.
Face validation runs on every capture regardless of roiShape.
import {
FaceCaptureScreen,
VALIDATION_CHECKS,
} from 'react-native-mlkit-face-capture';
// Only check face size and eyes open — skip centering, head angle, and landmarks
<FaceCaptureScreen
validations={[
VALIDATION_CHECKS.FACE_SIZE,
VALIDATION_CHECKS.EYES_OPEN,
]}
onCapture={handleCapture}
onGoBack={handleBack}
/>Available checks:
| Constant | Value | What it checks |
|----------|-------|----------------|
| VALIDATION_CHECKS.FACE_SIZE | 'faceSize' | Face occupies >= 28% of image width/height |
| VALIDATION_CHECKS.FACE_CENTERING | 'faceCentering' | Face center within 14% horizontal / 16% vertical of image center |
| VALIDATION_CHECKS.EYES_OPEN | 'eyesOpen' | Both eyes open probability > 55% |
| VALIDATION_CHECKS.HEAD_ANGLE | 'headAngle' | Yaw < 7deg, pitch < 8deg, roll < 8deg |
| VALIDATION_CHECKS.LANDMARK_GEOMETRY | 'landmarkGeometry' | Eye-nose symmetry, eye levelness, nose centering |
ALL_VALIDATIONS is also exported as a convenience — it's an array containing all five checks.
Using validateSelfie directly:
import { validateSelfie, VALIDATION_CHECKS } from 'react-native-mlkit-face-capture';
const result = await validateSelfie(
photoUri,
null, // use default strings
[VALIDATION_CHECKS.FACE_SIZE, VALIDATION_CHECKS.HEAD_ANGLE],
);Custom Strings
<FaceCaptureScreen
strings={{
takeSelfie: 'Tome una selfie',
positionYourFace: 'Posicione su rostro en el círculo',
noFaceDetected: 'No se detectó ningún rostro.',
// ... override any key from defaultStrings
}}
/>Exports
| Export | Type | Description |
|--------|------|-------------|
| FaceCaptureScreen | Component | Full capture screen with UI |
| defaultStyles | StyleSheet | Layout-only default styles (no colors) |
| useSetupCamera | Hook | Camera device + permission setup |
| CameraPreview | Component | Camera preview view |
| takePhoto | Function | Captures a photo from camera ref |
| validateSelfie | Function | ML Kit face validation |
| compressImage | Function | Image resize/compress |
| defaultStrings | Object | Default English strings |
| FACE_CAPTURE_CONSTANTS | Object | Camera positions, ROI shapes, and platform constants |
| VALIDATION_CHECKS | Object | Enum of individual validation check names |
| ALL_VALIDATIONS | Array | All validation checks (default for validations prop) |
Contact
Anweshan Mukherjee — [email protected]
