A React-based web application for analyzing and clustering faces from photo collections using AWS Rekognition.
This project is built with:
- Vite - Fast build tool and dev server
- TypeScript - Type-safe JavaScript
- React 18 - UI library
- shadcn/ui - High-quality React components
- Tailwind CSS - Utility-first CSS framework
- React Router - Client-side routing
- TanStack Query - Data fetching and caching
- Lucide React - Beautiful icons
- View clustered faces from your photo collection
- Search and filter people by ID
- Sort by photo count
- Responsive design with dark mode support
- Client-side caching for improved performance
- Photo lightbox for viewing details
Step by step instructions to build the project : beetroot-docs
- Node.js & npm installed
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
# Preview production build
npm run preview- AWS account + AWS CLI configured (
us-east-1) - Node.js + npm
- Python 3.12
AWS Rekognition collection
aws rekognition create-collection --collection-id beetroot --region us-east-1S3 buckets
aws s3 mb s3://beetroot-raw --region us-east-1
aws s3 mb s3://beetroot-thumbs --region us-east-1DynamoDB tables
Create these tables (default names used by Lambdas):
Photos(PK:photoIdstring)Persons(PK:personIdstring)Occurrences(PK:personIdstring, SK:photoIdstring)
- Ingest Lambda (S3 → Rekognition → DynamoDB + thumbs)
Use: backend/beetroot-ingest.py
Set env vars:
PHOTOS_TABLE=PhotosPERSONS_TABLE=PersonsOCCURRENCES_TABLE=OccurrencesRAW_PREFIX=photos-raw/THUMBS_BUCKET=beetroot-thumbsTHUMBS_PREFIX=faces-thumbs/REKOGNITION_COLLECTION_ID=beetrootFACE_MATCH_THRESHOLD=95
Add an S3 trigger on bucket beetroot-raw:
- event:
ObjectCreated:* - prefix:
photos-raw/
- API Lambda (HTTP API → DynamoDB + presigned URLs)
Use: backend/beetroot-api.py
Set env vars:
THUMBS_BUCKET=beetroot-thumbsPRESIGN_EXPIRES=3600PHOTOS_TABLE=PhotosPERSONS_TABLE=PersonsOCCURRENCES_TABLE=Occurrences
Create an API Gateway HTTP API with routes:
GET /personsGET /persons/{personId}/photos
Enable CORS for your frontend origin.
cd frontend
cp .env.example .envSet in frontend/.env:
VITE_API_BASE_URL=https://<your-http-api-invoke-url>Install + run:
npm install
npm run devUpload a photo to trigger processing:
aws s3 cp ./some.jpg s3://beetroot-raw/photos-raw/ --region us-east-1Then open the frontend:
- Click Load People
- Click a person → Load Images

