A fully client-side face recognition application that runs entirely in the browser. Your data never leaves your device - complete privacy guaranteed.
- Live Face Detection: Real-time face detection using your webcam
- Face Recognition: Match detected faces against your stored contacts
- 100% Client-Side: No server, no cloud, no data transmission
- Offline Support: Works offline after initial load via Service Worker
- Privacy First: All data stored locally in IndexedDB
- User Friendly: Responsive design with front camera support
- React 18 (Functional Components + Hooks)
- face-api (TensorFlow-based face detection)
- IndexedDB (via idb library)
- Service Worker for offline caching
- Modern ES6+ JavaScript
src/
├── components/ # React UI components
│ ├── AddPersonModal.jsx
│ ├── CameraView.jsx
│ ├── ConfirmDialog.jsx
│ ├── Controls.jsx
│ ├── EditPersonModal.jsx
│ ├── ErrorMessage.jsx
│ ├── LoadingIndicator.jsx
│ ├── OfflineIndicator.jsx
│ ├── PersonCard.jsx
│ ├── PersonList.jsx
│ ├── StatusBar.jsx
│ └── index.js
├── hooks/ # Custom React hooks
│ ├── useCamera.js
│ ├── useFaceDetection.js
│ ├── useModelLoader.js
│ ├── useOfflineStatus.js
│ ├── useStoredFaces.js
│ └── index.js
├── services/ # Business logic services
│ ├── faceDetection.js
│ ├── recognition.js
│ └── index.js
├── db/ # Database layer
│ ├── faceDB.js
│ └── index.js
├── utils/ # Utility functions
│ ├── similarity.js
│ ├── serviceWorker.js
│ └── index.js
├── models/ # (empty - models go in public/)
├── App.jsx # Main application component
├── App.css # Application styles
└── index.js # Entry point
public/
├── models/ # face-api.js model files
├── service-worker.js # Offline caching
├── index.html
└── manifest.json
cd "Context-ware personal memory assistant"
npm installDownload the required model files from the face-api repository:
Option A: Using the included script (Recommended)
npm run download-modelsOption B: Using curl/wget
# Create models directory
mkdir -p public/models
# Download TinyFaceDetector model
curl -o public/models/tiny_face_detector_model-weights_manifest.json \
https://raw.githubusercontent.com/vladmandic/face-api/master/model/tiny_face_detector_model-weights_manifest.json
curl -o public/models/tiny_face_detector_model.bin \
https://raw.githubusercontent.com/vladmandic/face-api/master/model/tiny_face_detector_model.bin
# Download FaceLandmark68 model
curl -o public/models/face_landmark_68_model-weights_manifest.json \
https://raw.githubusercontent.com/vladmandic/face-api/master/model/face_landmark_68_model-weights_manifest.json
curl -o public/models/face_landmark_68_model.bin \
https://raw.githubusercontent.com/vladmandic/face-api/master/model/face_landmark_68_model.bin
# Download FaceRecognition model
curl -o public/models/face_recognition_model-weights_manifest.json \
https://raw.githubusercontent.com/vladmandic/face-api/master/model/face_recognition_model-weights_manifest.json
curl -o public/models/face_recognition_model.bin \
https://raw.githubusercontent.com/vladmandic/face-api/master/model/face_recognition_model.binOption C: Manual Download
- Go to https://github.com/vladmandic/face-api/tree/master/model
- Download these files to your
public/models/folder:tiny_face_detector_model-weights_manifest.jsontiny_face_detector_model.binface_landmark_68_model-weights_manifest.jsonface_landmark_68_model.binface_recognition_model-weights_manifest.jsonface_recognition_model.bin
npm startThe application will open at http://localhost:3000
npm run buildThe built files will be in the build/ directory. You can serve them with any static file server.
- Click "Start Camera" to enable your webcam
- Detection automatically starts when camera is active
- Detected faces show bounding boxes (green = known, orange = unknown)
- Position a face clearly in the camera view
- Wait for the face to be detected (face count badge appears)
- Click "Add Person"
- Enter the person's name and optional note
- Click "Save Person"
- Find the person in the list on the right
- Click the edit (pencil) icon
- Update name or note
- Click "Save Changes"
- Find the person in the list
- Click the delete (trash) icon
- Confirm deletion
After the first load, the application works completely offline:
- All JS/CSS bundles are cached
- Face detection models are cached
- Your data is stored in IndexedDB
An "Offline Mode" indicator appears when disconnected.
The default recognition threshold is 0.55 (55% similarity). You can adjust this in src/utils/similarity.js:
export const DEFAULT_THRESHOLD = 0.55;- Lower values (0.45): More matches, more false positives
- Higher values (0.65+): Fewer matches, more strict
Face detection runs every 500ms by default. Adjust in src/hooks/useFaceDetection.js:
const DEFAULT_INTERVAL = 500; // millisecondsMaximum 50 people can be stored. Adjust in src/db/faceDB.js:
const MAX_STORED_FACES = 50;- Use WebGL: Ensure your browser supports WebGL for GPU acceleration
- Good Lighting: Well-lit faces are detected faster and more accurately
- Stable Camera: Keep the camera steady for consistent detection
- Reduce Resolution: The app automatically uses 640x480, which is optimal
- Model loading: ~2-5 seconds (cached after first load)
- Face detection: <500ms per frame
- Recognition matching: <100ms
- Total recognition cycle: <800ms
- Chrome 80+ (recommended)
- Firefox 75+
- Safari 14+
- Edge 80+
Requirements:
- WebGL support (falls back to CPU if unavailable)
- IndexedDB support
- Service Worker support (for offline mode)
- Camera/getUserMedia support
- No Network Requests: After initial load, zero network activity
- Local Storage Only: All face data stored in browser's IndexedDB
- No Telemetry: No analytics, no tracking, no data collection
- No Cloud: No server-side processing whatsoever
- Your Data: Completely under your control
The application handles these error scenarios:
| Error | Handling |
|---|---|
| Camera denied | Shows permission request message with retry |
| Camera unavailable | Shows device not found message |
| Camera in use | Shows busy message |
| No face detected | Shows positioning guidance |
| Multiple faces | Processes all faces |
| Model loading failed | Shows retry option |
| IndexedDB unavailable | Shows storage error |
| WebGL unavailable | Falls back to CPU (slower) |
| Storage quota exceeded | Shows limit reached message |
- Lighting Sensitivity: Poor lighting reduces accuracy
- Angle Sensitivity: Works best with frontal faces
- Storage Limit: Maximum 50 people (IndexedDB constraint)
- Browser Tab: Detection pauses when tab is hidden
- Mobile Performance: Slower on low-end mobile devices
- Single Embedding: Each person has one stored embedding
- Multiple Embeddings: Store multiple angles per person
- Face Quality Score: Reject poor quality captures
- Export/Import: Backup and restore face data
- Threshold Slider: UI control for recognition sensitivity
- Face Grouping: Automatic clustering of unknown faces
- Statistics: Recognition accuracy metrics
- PWA Install: Add to home screen functionality
- Dark Mode: Theme toggle support
- Check browser permissions (click lock icon in URL bar)
- Ensure no other app is using the camera
- Try a different browser
- Check if camera works in other apps
- Check internet connection (first load only)
- Verify model files exist in
public/models/ - Check browser console for errors
- Try clearing browser cache
- Ensure good lighting
- Face the camera directly
- Check if the person was added correctly
- Try lowering the threshold
- Service worker requires HTTPS or localhost
- Clear site data and reload
- Check browser supports service workers
MIT License - Use freely for personal and educational purposes.
- face-api.js by Vladimir Mandic
- TensorFlow.js by Google
- idb by Jake Archibald