Designing a Kindle-style mobile reading app is a layered system design problem. Format rendering, position sync across devices, offline downloads, annotations and highlights, library organization — and the unique constraint of preserving battery during multi-hour reading sessions on a phone or e-reader.
Functional requirements
- Browse a personal library of purchased and free ebooks
- Read ePub or proprietary format with reflowable text
- Sync reading position across devices
- Highlights, notes, bookmarks, and dictionary lookup
- Search within a book and across the library
- Adjust font size, brightness, theme
Architecture
Three modules: library (purchases, downloads), reader, sync.
Format and rendering
Most reading apps use ePub (open format) or proprietary formats derived from it. ePub is essentially HTML + CSS in a zip, with metadata.
Rendering on mobile:
- Parse ePub into chapters and assets
- Apply user-controlled CSS (font, size, line height)
- Lay out into pages — page boundaries shift as user changes settings
- Cache rendered pages for fast scrolling
Position sync
The challenge: page numbers are not stable across devices. A page on a small phone is different from a page on a tablet. Solution: track position by character offset within the book, not by page.
Sync flow:
- Reader periodically (every 30s or on app background) pushes position to server
- On app launch, fetch latest positions across all devices
- If multiple devices show different positions, default to the most-recent (with HLC for clock-skew tolerance)
- Surface a UI prompt: “Continue from page X on iPad?”
Annotations and highlights
Each annotation is anchored to a character range. Stored as:
- Book ID
- Start offset, end offset
- Highlighted text (for display when range fails to resolve)
- Color, note text
- Created/updated timestamps
Synced across devices like position. Server is the source of truth; local SQLite caches recent annotations.
Offline downloads
Books are downloaded once, stored on disk encrypted with a per-device key (DRM). User can have multiple devices in sync. Cloud-side library lists all owned books; the device chooses what to download.
Storage budget: typical user has 50–500 books. Most are 0.5–10MB. Reasonable footprint.
Search
Within a book: local FTS5 (SQLite full-text). Within the entire library: server-side search with snippets returned. Combined UI shows local + server results.
Reading-time battery
Reading sessions are long. Battery optimizations:
- Pre-render upcoming pages off-thread; render visible page from cache
- Disable background sync during reading
- Lower display brightness with auto-detect of ambient light
- For e-readers: e-ink draws nearly zero power between page flips
The “where am I in the book” UX
Page numbers are unstable; books often show:
- Percentage complete
- Time-to-end (based on user reading speed)
- Chapter title
- Location (“Loc 2547” — Kindle’s position-based addressing)
Frequently Asked Questions
Why do annotations sometimes shift on Kindle?
Updates to the book file change byte offsets. Annotations may be re-anchored heuristically; rarely they end up off by a page or two.
How does dictionary lookup work?
Bundled dictionary database (often Webster’s). On long-press, lookup is local — no network needed.
Why is e-ink different from LCD for reading?
E-ink uses ambient light, displays static images with zero power, easier on eyes. LCD emits light, faster refresh, full color. Tradeoffs are real — many serious readers own both.