ariadne is a modern EPUB reading app designed for people who read deeply.
Its main feature is this: open any book and return exactly to where you left off. Then ariadne gives you AI summarization and AI context understanding of what you have already read, so you restart with clarity instead of confusion.
In the old myth, Ariadne gives a thread so you can always find your way back out. In this app, that thread is your reading position and your reading memory: close a book at page 47, come back a week later, and ariadne takes you to the exact line where you paused, then reminds you with AI summaries and context of what came before.
Most reading apps are either too basic or overloaded. ariadne is built around real reading behavior:
- Find your place fast
- Understand what matters on the page with AI context
- Save what you want to remember
- Come back later without friction, exactly where you left off
- Upload EPUB books in seconds
- Bulk upload support (select multiple EPUB files at once)
- Upload feedback: one batch popup with:
- Overall progress (
current/totalbooks in the batch) - Current file progress (green bar per active file)
- Overall progress (
- Duplicate upload guard (single or batch): per-file prompt to ignore, replace (with data loss warning), or keep both with numbered duplicate titles (
Duplicate 1,Duplicate 2, etc.) - Bulk upload path optimized for speed:
- One library refresh after the full batch (instead of reloading after each file)
- In-memory duplicate index while processing each file
- EPUB metadata extraction runs in a Web Worker to keep upload UI responsive on heavy files/batches
- Automatic fallback to main-thread parsing if Worker is unavailable
- Yellow success toast after upload and a 10-second halo on newly added book cards
- Clean cover-based library with a 3-mode view toggle:
Grid(standard cards)Compact Grid(denser 3x3-style icon mode for large libraries)List
- Compact Grid reduces cover/card footprint to fit more books on screen and keeps only essential card info (
title+author) - Smart metadata (author, language, estimated pages, year, and genre when available)
- Genre auto-detection improved from EPUB metadata (
subject,dc:subject,type,dc:type, and related fields) with normalized labels - Book Info popover on each card (hover/click) with cleaned EPUB metadata:
- Prioritized order for key fields (
Title,Author,Language) - Hidden noisy/empty entries (for example
modified,identifier, and blank values) - Language labels shown in full form (
English,French, etc.)
- Prioritized order for key fields (
- Clean inline metadata rows on cards (lightweight language/pages display)
- Workspace sidebar for fast section switching:
My Library,My Collections,Notes,Highlights,Trash,Settings - Dedicated brand slot at the top of the left sidebar for app identity:
public/brand/logo-light.pngin light modepublic/brand/logo-dark.pngin dark mode
- Reading Snapshot panel above the workspace sidebar:
- Completion donut (
finished / total) - Total hours spent across all books
- Total pages from completed books only
- Reading time for today
- Completion donut (
- Dedicated Reading Statistics workspace with focused, simple metrics:
- Reading Time and Estimated Pages
- Current streak and monthly reading days
- Monthly heatmap (darker = more reading, lighter = less)
- Status distribution and top books
- Sidebar + snapshot visuals aligned with the same card language as Continue Reading (rounded cards, stronger hierarchy, cleaner iconography)
- Search, filter, and sort to find the right book fast
- Custom shelves (collections): create, rename, delete, and color-code your own reading buckets
- Assign books to one or many shelves directly from each card
- Dedicated
My Collectionsworkspace with scalable default layout:Directory + Detailview (left collections list, right selected collection books)- Built-in collection search for fast switching at scale (
10+collections) - Add books directly from collection view with in-context modal picker
- Optional
Boardtoggle for overview mode:- Fixed responsive columns (
4desktop,2tablet,1mobile) - Balanced auto-placement by collection size for cleaner scanning
- Quick “View all books” jump back into Directory detail mode
- Fixed responsive columns (
- Sticky library toolbar (search, filters, sort, view mode always visible while scrolling)
- Quick filter count chips (
To read,In progress,Finished,Favorites) with one-click filtering - Combine
Statusfiltering with quickFavoritesfiltering when needed - One-click
Reset filtersaction to return search/filter/sort to default - Large-library rendering optimization:
- Incremental card rendering in grid/list views (books are loaded in chunks while scrolling)
- Helps keep scrolling smooth and initial render faster with heavy libraries
- Debounced library search and memoized heavy selectors to keep typing and filtering responsive at scale
- Persistent IndexedDB search index for metadata, highlights, notes, and bookmarks (faster repeat searches after reload)
- Persistent in-book content index stored in IndexedDB to reduce repeated full-EPUB scans during global content search
- Worker-assisted section candidate matching before EPUB CFI resolution (fewer sections searched per query)
- Route-level lazy loading (
Home/Reader) to reduce initial bundle cost - On-demand loading for export libraries (
jspdf,html2canvas,jszip) only when export actions are used - Render culling with
content-visibility: autoon large repeated rows/cards (library, notes, highlights, global search)
- Manual
TO READtagging (create your personal "read next" queue) - Favorites with cleaner, less cluttered library cards
- Dedicated Notes workspace with cross-book note browsing, inline editing, and jump-to-reader
- Dedicated Highlights workspace with cross-book highlight browsing and jump-to-reader
- Continue Reading rail redesigned with layered cover cards, progress ring, optional favorite marker, and estimated time-left hint
- Dedicated Trash workspace (independent from library filters):
- Trash-specific search and sort
- Grid/list views
- Bulk actions:
Select all/Unselect all,Restore selected,Delete selected,Restore all,Delete all - 30-day retention notice and auto-purge handling
- Reliable per-book checkbox selection (manual one-by-one and bulk selection parity)
- Permanent delete backup flow:
- Single book: optional PDF + JSON export (highlights and notes)
- Multiple books: optional ZIP export with one folder per book (
PDF+JSON) - If a book has no highlights/notes, no backup prompt is shown
- Top-right
Dark mode / Light modetoggle directly in the library header - Top-right header controls now include:
- Notifications bell with unread badge
- Profile avatar menu (
Profile,Reading Statistics,Settings,FAQ,Sign out) - Custom profile pictures and display names (set in Settings)
- Notification Center with
All/Unreadtabs - Notification actions menu (
...) per item:Open in Reader,Mark as read/unread,Archive,Delete - Notification card click focuses/highlights the related book in
Continue Reading - Reading nudges and activity alerts:
- Finish-soon (
<= 30 min) - Streak risk
- Resume abandoned in-progress books
- Daily micro-goal
- Milestone reached (25/50/75/90%)
- To-read reminder
- Finish-soon (
- Optional performance debug traces for heavy libraries:
- Set
localStorage.setItem("library-perf-debug", "1")to logload/uploadtimings in DevTools - Read session timings from
window.__smartReaderPerfHistory
- Set
- Paginated and infinite-scroll modes
- First-open reading mode choice is mandatory per book:
- choose
Book vieworInfinite scrollingonce before reading starts - chosen mode stays locked while the book is in progress
- reopening an already in-progress book does not re-trigger this chooser
- changing mode later uses a guided flow (
Change reading mode) with mandatory relocation:Restart book:- jumps to the beginning
- resets book progress to
0%
Choose chapter:- jumps to selected chapter
- updates progress based on that chapter position in the table of contents
- choose
- Paginated mode supports subtle edge click/tap zones for next/previous page turns (no intrusive on-page arrow buttons)
- Centered portrait-style reading column in scroll mode
- Per-book reading preferences:
- Theme
- Font size
- Font family
- Line spacing (continuous slider, not fixed presets)
- Text alignment
- Page width control (available in
Infinite scrollingmode only) - Reading flow
- Light mode, dark mode, and sepia reading mode
- Reader text settings control uses the standard
Aaicon - Upper-right reader icon controls include hover tooltips for faster discoverability
- Keyboard navigation support (Left/Right in paginated mode, Up/Down in infinite mode with gradual acceleration on hold)
- Chapter menu + table of contents navigation
- Centered current chapter label in the reader header (derived from TOC + current location)
- Reader search keyboard shortcuts (
Ctrl+Fto open search,Escto close) - Return-to-previous-spot chip after navigation jumps (search, highlights, bookmarks, notes, TOC)
- Dictionary lookup cancels stale responses when you close the panel
- Footnote/endnote marker preview popup:
- Click in-book note marker links (for example
[1]) to open an anchored preview - Jump directly to the full note target with
Open full note - Quick dismiss on outside click,
Esc, or viewport change
- Click in-book note marker links (for example
- In-reader search with result navigation (
X/N, next/previous) - Active search result stays synchronized between text highlight and result list auto-scroll
- In-book search markers are applied reliably while search is active and cleared cleanly on
Clear/close - Clicking a search result pins a temporary green focus marker at that exact reading location
- Recent query history in both reader search panels (book search + annotation search) with one-click re-run and reset
- Dedicated in-reader annotation search (separate icon/panel) for current-book highlights, highlight notes, and bookmarks
- Annotation search results jump directly to saved CFIs, with highlight/note matches flashing for quick visual confirmation
- Global search across:
- Book metadata
- Highlights
- Notes
- Bookmarks
- In-book content
- Global search opens exact reader location with context preserved
- Multi-color highlights
- Highlight anchors are content-stable across reader style/layout changes:
- same highlighted text is preserved when changing font size/family, line spacing, margins, alignment, and flow mode
- quote/context recovery is used when a raw CFI no longer maps cleanly after reflow
- One-click
Highlightnow applies your most recently used color Colorschooser is ordered by recency (last used color appears first)- Highlights panel defaults to no pre-selected items (
Select all/Unselect allworkflow) - Re-clicking an existing highlight opens a contextual action popup anchored next to that highlight (delete, dictionary, translate)
- Existing highlights support in-place color changes from the same contextual popup (no delete/recreate needed)
- Right after choosing a highlight color, an inline note composer opens near the selection so notes can be captured immediately
- Highlights that include notes now show an inline note marker (
✎) near the text; clicking it opens the note editor directly - Highlight deletion now includes a 5-second undo toast in the reader
- Add and edit notes on highlights
- Jump to any saved highlight instantly
- Highlight jumps use a single subtle flash cue (in panel and when opening from Highlights Center)
- Bookmarks for key pages
- Dictionary and translation from text selection
- Export highlights to PDF (select all or specific items)
- Accurate per-book progress tracking
- Estimated time left
- Reading sessions and “last session” snapshot (with inline icon cues in library cards)
- Reading streak badge on home
ariadne is fully usable for everyday reading workflows.
AI buttons are visible in the UI, but AI features are currently marked as unavailable.
npm install
npm run devOpen the app at the local Vite URL (usually http://localhost:5173).
- Open a new book, choose reading mode, read enough to create non-zero progress, close reader.
- Reopen the same book:
- expected: no mode chooser appears.
- In reader, click
Change reading modethenRestart book:- expected: progress becomes
0%.
- expected: progress becomes
- In reader, click
Change reading modethenChoose chapter:- expected: progress updates relative to selected chapter position.
This repository now includes a collaborative backend for multi-user sharing on one server.
- One shared server runs
docker-compose(backend + postgres). - All users access the app from a browser over your private network.
- No per-user Docker setup is required.
- Public internet exposure is optional.
- Copy backend env:
cp server/.env.example server/.env- Set at least:
JWT_SECRETto a strong secret.APP_BASE_URLto your backend URL, for examplehttp://<SERVER_IP>:4000.
- Start backend + DB:
docker compose up -d --build backend db- Optional: run frontend in Docker too:
docker compose --profile frontend up -d --build frontendSet VITE_API_BASE_URL to your backend URL (for example http://<SERVER_IP>:4000).
When this variable is set:
- Email/password registration/login is enabled.
- Display name is required at signup.
- JWT auth is required.
- Books/progress/highlights are loaded from shared backend.
- Recommendation Inbox, Borrowed, Lent, and History sections are enabled.
- Profile avatar upload and profile name updates are enabled.
Bookis global/shared byepubHash.- Per-user progress is in
UserBook. - Sharing is recommendation-first:
Sharesends book recommendation metadata.- Recipient chooses whether to borrow.
- Lending creates a
BookLoanwith immutable permission snapshot at creation/accept. - Borrower progress is always independent from lender progress.
- Notes/highlights use scoped visibility:
OWNERLENDER_VISIBLEPRIVATE_BORROWER
- Borrowed annotation permissions are enforceable per loan:
- add/edit notes
- add/edit highlights
- borrower cannot edit/delete lender annotations.
- Lender can choose whether borrower can see lender existing annotations (
shareLenderAnnotations). - Borrower annotations do not affect lender reading state or progress.
- Book access requires
UserBookrelation. - Recommendation records are stored in
BookShare. - Loan events/timeline are stored in
LoanAuditEventand shown inHistory. - Loan renewal workflow:
- Borrower can request extension days.
- Lender can approve or deny.
- Renewal actions are audited and notified.
- Default lending template per user:
- Saved server-side (
duration,grace, permission defaults, reminder days). - New loan requests use template defaults automatically unless overridden.
- Saved server-side (
- Loan state visibility in UI:
- Book cover badges in library and continue-reading:
- no badge = owned/non-loan
Borrowedbadge = active borrowed loanLentbadge = active lent loan
- Library filter includes
Borrowed booksandLent books.
- Book cover badges in library and continue-reading:
- Collaboration workspace tabs:
My library,Borrowed,Lent,History,Inbox.
- Borrowed/Lent pages include richer book-first cards with cover thumbnails and view controls:
GridCompactList
- Loan accept flow now includes a permission-summary confirmation step before final accept.
- Borrowed and Lent views include renewal controls:
- borrower can request extension days,
- lender can approve/deny pending renewal requests.
- History is grouped at book level:
- all lifecycle events for the same book are shown together
- each event row shows actor/target identity with small avatar chips.
- Inbox has two collaboration streams:
- recommendation shares (
BookShare) - loan inbox (
BookLoanrequests).
- recommendation shares (
- Borrow reminders are surfaced in both:
- Notification Center events (
due soon,overdue) - Inbox
Borrow Reminderspanel.
- Notification Center events (
- Notification reliability (server-side):
- Loan notifications are persisted in backend (
UserNotification) with stable per-usereventKey. - Read/archive/delete state is persisted server-side.
- Notification actions in UI call backend mutation endpoints.
- Loan notifications are persisted in backend (
- Central entitlement and policy logic is enforced server-side for loan reads/writes.
- Notes/highlights updates use revision conflict protection:
- Send
if-match-revisionheader to avoid overwriting newer server edits. - Backend returns
409 REVISION_CONFLICTwhen stale.
- Send
- Borrower/lender permissions are snapshotted in loan record at request/accept time.
PENDING->ACTIVEon borrower accept.ACTIVEcan become:RETURNED(borrower returns),REVOKED(lender revokes anytime),EXPIRED(due + grace exceeded).
- On
RETURNED/REVOKED/EXPIRED:- reader access is blocked immediately,
- book appears as ended state in Borrowed view,
- only export actions remain available.
- Borrower can export their annotations for 14 days after loan end.
- Export formats in UI:
JSONPDF(summary export)
- After export window ends, annotations are no longer accessible through loan export endpoints.
- In
Settings, users can defineBorrow reminder (days before due)with range0..30. 0disables due-soon reminders.- Due-soon and overdue reminders are generated from active borrowed loans.
- Backend includes a maintenance scheduler for:
- automatic active-loan expiry transition,
- due-soon and overdue notification generation,
- ended-loan export-window reminders.
Environment variables:
LOAN_SCHEDULER_ENABLED=true|false(defaulttrue)LOAN_SCHEDULER_INTERVAL_MS(default60000, minimum15000)server/.env.exampleanddocker-compose.ymlalready expose these values.
When pulling latest collaboration changes, run migrations on the server DB:
docker compose exec backend npx prisma migrate deployThen rebuild/restart backend/frontend so API + UI match:
docker compose up -d --build backend frontendsrc/pages/Home.jsx- Library page orchestrator (state, data loading, feature composition)src/pages/library/LibraryWorkspaceNav.jsx- Sidebar and mobile workspace navigationsrc/pages/library/LibraryToolbarSection.jsx- Library search/filter/sort toolbar + active chips + view togglesrc/pages/library/LibraryCollectionsBoard.jsx- Collections workspace (Directory + Detaildefault, optional balanced board toggle, add-books modal)src/pages/library/LibraryNotesCenterPanel.jsx- Notes workspace pagesrc/pages/library/LibraryHighlightsCenterPanel.jsx- Highlights workspace pagesrc/pages/library/LibraryGlobalSearchPanel.jsx- Global search result panelsrc/pages/library/LibraryAccountSection.jsx- Settings section formsrc/pages/Reader.jsx- Reading experience, contextual tools, highlights, bookmarks, export, and search handoffsrc/components/BookView.jsx- EPUB rendering and navigation enginesrc/services/db.js- Local-first persistence layersrc/services/searchIndex.js- Persistent search index builder/storage for fast library + global searchsrc/services/contentSearchIndex.js- Persistent in-book section text index for faster content searchingsrc/services/contentSearchWorkerClient.js- Worker client for fast candidate section matching during content search
If you want a reader that feels practical on day one and scalable for serious reading habits, ariadne is built for that.