Library Management
How Alex ingests, organizes, and displays your books
Alex keeps your library in sync automatically. It supports two ingestion backends:
- Local mode - Watches a filesystem folder for file events
- S3 mode - Polls an S3-compatible bucket and diffs object changes
Ingestion engine
A Rust service (watcher-rs) handles ingestion, metadata extraction, cover generation, and database updates.
Local mode
When files in your library folder change, Alex processes them within seconds:
- New files - Extract metadata, generate a cover, and create a new book record.
- Modified files - Re-hash and reprocess metadata if content changed.
- Deleted files - Remove the book, related progress records, and collection associations.
S3 mode
Alex periodically polls your bucket/prefix and computes diffs:
- Added objects - Ingested as new books
- Changed objects - Reprocessed and updated
- Removed objects - Removed from the library and cleanup applied
Only .pdf and .epub content is ingested.
Deduplication
Alex computes a SHA-256 hash for each book. If an identical file/object already exists, duplicates are skipped.
Initial reconciliation
At startup, Alex reconciles current source state with the database so records stay consistent after downtime.
Library browsing
The library page shows books in a responsive grid with covers, titles, and authors.
Search
Search title or author with debounced, case-insensitive matching.
Filtering
- File type - All, PDF, EPUB
- Reading status - All, not started, reading, completed
Sorting
- Title (A-Z)
- Author (A-Z)
- Recently added
- Recently read
Cover images
Cover generation is handled by the Rust pipeline:
- PDF - Rendered from page 1 using
pdfium-render - EPUB - Extracted from embedded cover metadata when available
- Fallback - Generated synthetic cover when extraction fails
Continue Reading
A dedicated "Continue Reading" section shows in-progress books ordered by most recent activity. Selecting one jumps you back to your saved position.