A CLI tool for organizing family photos using face recognition. Automatically identifies family members in your photo library and organizes them into Apple Photos albums.
- Scans your photo library (local folders, iCloud Photos, Telegram exports)
- Recognizes faces using AWS Rekognition
- Remembers what it's scanned (no duplicate processing)
- Learns from your corrections (approve/reject matches)
- Organizes photos into Apple Photos albums by person
- Bun runtime: https://bun.sh
- AWS Account with Rekognition access
# Clone the repository
git clone https://github.com/leonprou/openbook.git
cd openbook
# Install dependencies
bun install
# Install globally (makes 'openbook' command available anywhere)
bun linkOnly required if you want to export albums to Apple Photos:
uv tool install osxphotos
# or: pip install osxphotosIf you prefer not to install globally, run commands from the project directory:
bun run start <command>
# Example: bun run start init# 1. Initialize (creates global config at ~/.config/openbook/)
openbook init
# 2. Train with reference photos
# Create folders: ./references/mom/, ./references/dad/, ./references/kid1/
# Add 3-5 clear face photos to each folder
openbook train -r ./references
# 3. Scan your photo library
openbook scan ~/Pictures/Family
# 4. Review and correct any mistakes
openbook reject --person "Mom" --photo ~/Pictures/wrong_match.jpg
# 5. Re-scan uses cache, so it's fast!
openbook scan ~/Pictures/FamilyThe config and database are stored globally in ~/.config/openbook/, so you can run openbook from anywhere.
| Command | Description |
|---|---|
openbook init |
Initialize config and AWS Rekognition collection |
openbook train -r <path> |
Index faces from reference folders |
openbook scan <path> |
Scan photos and create review albums |
openbook scan <path> --dry-run |
Preview what albums would be created |
openbook scan <path> --rescan |
Force re-scan of cached photos |
openbook approve |
Approve review albums and create final albums |
openbook approve --person "Name" --photo <path> |
Approve a specific recognition |
openbook reject --person "Name" --photo <path> |
Mark recognition as incorrect |
openbook add-match --person "Name" --photo <path> |
Manually add a missed recognition |
openbook status |
Show collection info and database stats |
openbook cleanup |
Remove AWS collection |
openbook remembers every photo it scans using a local SQLite database (.openbook.db).
- SHA256 Hashing: Each photo is identified by its content hash, not filename
- Smart Caching: Already-scanned photos use cached results (no AWS calls)
- Move-Friendly: Renamed or moved files are still recognized
- Re-scan Option: Use
--rescanto force fresh recognition
$ openbook scan ~/Photos
Scanning |โโโโโโโโโโโโโโโโ| 100% | 1234/1234 | Matched: 89 | Cached: 892
Matches found:
Mom: 45 photos (avg 92.3% confidence)
Dad: 38 photos (avg 88.7% confidence)
Sister: 6 photos (avg 95.1% confidence)
Cache stats: 892 from cache, 342 newly scanned
When face recognition makes mistakes, teach it:
If "Mom" was incorrectly detected in a photo:
openbook reject --person "Mom" --photo ~/Photos/vacation/IMG_001.jpgFuture scans will exclude this match.
If "Dad" is in a photo but wasn't detected:
openbook add-match --person "Dad" --photo ~/Photos/vacation/IMG_002.jpgFuture scans will include this match.
To mark a match as verified correct:
openbook approve --person "Mom" --photo ~/Photos/vacation/IMG_003.jpgโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CLI Layer โ
โ init | train | scan | approve | reject | add-match | status โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Core Pipeline โ
โ 1. Hash photo โ 2. Check cache โ 3. Detect faces โ
โ 4. Match people โ 5. Apply corrections โ 6. Create albums โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโ
โผ โผ โผ
โโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโ
โ Photo Sources โ โ Recognition โ โ Local Databaseโ
โโโโโโโโโโโโโโโโโค โโโโโโโโโโโโโโโโโค โโโโโโโโโโโโโโโโโค
โ Local folders โ โ AWS โ โ SQLite โ
โ iCloud Photos โ โ Rekognition โ โ Persons โ
โ Telegram โ โ โ โ Photos โ
โ โ โ โ โ Corrections โ
โโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโ
โ Album Export โ
โโโโโโโโโโโโโโโโโค
โ osxphotos โ
โ Apple Photos โ
โโโโโโโโโโโโโโโโโ
-
Training Phase
Reference Photos โ Detect Faces โ Index to AWS Collection ./references/mom/*.jpg โ face vectors โ "openbook-faces" collection -
Scanning Phase
Photo Library โ Hash โ Cache Check โ Match Against Collection โ Apply Corrections โ Create Albums ~/Pictures/*.jpg โ SHA256 โ cached? โ "mom: 94%" โ not rejected? โ "openbook: Mom" album
Photos with multiple recognized people are added to all matching albums:
- Photo with Mom + Dad โ added to both "openbook: Mom" AND "openbook: Dad"
| Technology | Purpose |
|---|---|
| Bun | Runtime - fast TypeScript execution |
| TypeScript | Type-safe development |
| AWS Rekognition | Face detection and recognition (~$1/1000 photos) |
| SQLite | Local database for caching and corrections |
| osxphotos | Apple Photos album creation |
@aws-sdk/client-rekognition - AWS face recognition API
better-sqlite3 - SQLite database for photo memory
sharp - Image processing and resizing
commander - CLI framework
zod - Config validation
bottleneck - API rate limiting
ora, cli-progress - CLI progress indicators
Configuration is stored at ~/.config/openbook/config.yaml (created by openbook init).
For project-specific settings, create a local config with openbook init --local. Local configs take precedence over global.
Example config:
aws:
region: us-east-1
rekognition:
collectionId: openbook-faces
minConfidence: 80 # Minimum match confidence (0-100)
sources:
local:
paths:
- ~/Pictures/Family
extensions:
- ".jpg"
- ".jpeg"
- ".png"
- ".heic"
training:
referencesPath: ./references
albums:
prefix: "openbook" # Albums: "openbook: Mom", "openbook: Dad"# AWS credentials (or use ~/.aws/credentials)
AWS_ACCESS_KEY_ID=your_key
AWS_SECRET_ACCESS_KEY=your_secret
AWS_REGION=us-east-1To create restricted IAM credentials that prevent accidental data loss:
# See docs/AWS-Setup-Openclaw.md for full setup instructions
./scripts/setup-openclaw-iam.shThe restricted policy allows training and scanning but blocks collection deletion. Perfect for AI agents that need controlled access to AWS Rekognition.
Organize reference photos with one folder per person:
references/
โโโ mom/
โ โโโ photo1.jpg # Clear face, good lighting
โ โโโ photo2.jpg # Different angle
โ โโโ photo3.jpg # 3-5 photos recommended
โโโ dad/
โ โโโ photo1.jpg
โ โโโ photo2.jpg
โโโ kid1/
โโโ photo1.jpg
โโโ photo2.jpg
Tips for reference photos:
- Use clear, well-lit photos with one face per image
- Include different angles and expressions
- 3-5 photos per person is usually sufficient
- Avoid group photos for training
openbook stores data in ~/.config/openbook/:
| File | Purpose |
|---|---|
config.yaml |
Your configuration |
.openbook.db |
SQLite database with all scan data |
.openbook-session.json |
Temporary session state |
Optionally, create a local ./config.yaml for project-specific settings (takes precedence over global).
- persons: People from training (name, face count, photo count)
- photos: Scanned photos with recognitions and corrections
- scans: History of scan runs with statistics
- recognition_history: Full audit trail of all recognitions
iCloud Photos syncs to a local folder on macOS. Point openbook at the Photos Library:
# Scan iCloud Photos library
openbook scan ~/Pictures/Photos\ Library.photoslibrary/originalsOr export photos first for better results:
- Select photos in Apple Photos
- File โ Export โ Export Unmodified Originals
openbook scan ~/exported-photos
Family photos are often shared in Telegram groups:
- Open Telegram Desktop (not mobile app)
- Go to the group chat with family photos
- Click โฎ โ Export chat history
- Check Photos, choose export location
- Click Export
openbook scan ~/Downloads/TelegramExport/photosopenbook uses AWS Rekognition, which is not free but is very affordable for personal use.
- Face Detection: ~$1.00 per 1,000 images
- Face Search: ~$1.00 per 1,000 searches
- Storage: $0.01 per 1,000 face vectors per month
| Scenario | Photos | Cost (one-time) | Monthly Storage |
|---|---|---|---|
| Small library | 1,000 photos | ~$2 | ~$0.01/month |
| Medium library | 10,000 photos | ~$20 | ~$0.10/month |
| Large library | 50,000 photos | ~$100 | ~$0.50/month |
- Use the cache: Re-scanning cached photos is free (no AWS calls)
- Start small: Test with
--limit 500before scanning your entire library - Train efficiently: Only 3-5 reference photos per person needed
- Review before export: Fix mistakes before creating albums (no re-scanning needed)
AWS Free Tier includes:
- 1,000 faces stored per month (first 12 months)
- 1,000 face searches per month (first 12 months)
For most personal photo libraries, costs are minimal after the initial scan.
Increase the confidence threshold in config.yaml:
rekognition:
minConfidence: 90 # Higher = fewer but more accurate matchesLower the confidence threshold:
rekognition:
minConfidence: 70 # Lower = more matches, some may be wrongUse reject command to fix any mistakes.
MIT