A beautiful, offline-first EPUB reader that runs in your browser.
Drag in your books, browse your library, and start reading — no accounts, no servers, no compromises.
Features · Architecture · Roadmap
Visit https://exstudeo.github.io/ You can also install it as PWA!
Most EPUB readers are either bloated desktop apps or cloud services that hold your library hostage. Exstudeo is different — it's a fully self-contained web app. Your books stay on your device, served from your local filesystem through a lightweight virtual file layer. The entire app works offline after the first visit, thanks to a carefully crafted service worker.
ex·stu·de·o (Latin) — "I study thoroughly, I am eager, I strive."
|
Full EPUB 2 & 3 support with a responsive two-column layout: collapsible table-of-contents sidebar on the left, beautifully typeset content on the right. The sidebar automatically tracks your reading position as you navigate. |
The Library is stored on your own machine with File System Access API. Your Data is safe and can easily work with any backup/sync service. |
|
A Progressive Web App with a service worker that pre-caches the entire application shell. Once loaded, you can read anywhere — on the subway, in a plane, or deep in the woods. |
Respects your system theme with a polished dark mode. Reading content is set in a comfortable serif face at a generous line-height, optimized for long-form reading sessions. |
|
Zero telemetry. Zero accounts. Your books never leave your device. All file access goes through the browser's File System Access API — you control exactly what folders are mounted. |
Every EPUB page passes through an HTML rewrite pipeline in the service worker that strips scripts, inline styles, and event handlers before the page reaches your eyes. Publisher cruft is gone; only clean, readable content remains. |
Exstudeo is a monorepo powered by Turborepo with two workspaces:
┌─────────────────────────────────────────────┐
│ Browser │
│ ┌──────────────┐ ┌───────────────────┐ │
│ │ React 19 │ │ Service Worker │ │
│ │ (app shell) │◄──►│ (offline + EPUB) │ │
│ └──────┬───────┘ └────────┬──────────┘ │
│ │ │ │
│ ┌──────▼──────────────────────▼──────────┐ │
│ │ ZenFS Virtual FS │ │
│ │ (POSIX API over FSA handles) │ │
│ └──────┬─────────────────────────────────┘ │
│ │ │
│ ┌──────▼──────┐ │
│ │ IndexedDB │ (mount persistence) │
│ └─────────────┘ │
└─────────────────────────────────────────────┘
| Layer | Technology | Role |
|---|---|---|
| App Shell | React 19 + React Router v7 + shadcn/ui | Tabbed UI with file explorer & reader |
| Styling | Tailwind CSS 4 + base-nova theme | Dark/light system, semantic tokens, RTL |
| Service Worker | Workbox + injectManifest | Offline precaching, three-tier routing, EPUB HTML rewrite |
| Virtual FS | ZenFS (@zenfs/core + @zenfs/dom) |
POSIX filesystem over File System Access API |
| Build | Vite 7 + TypeScript 5.9 strict | Multi-entry builds, PWA manifest auto-generation |
| Testing | Vitest + React Testing Library + jsdom | Co-located tests, CI-ready |
| Monorepo | Turborepo + npm workspaces | Orchestrated build, lint, typecheck |
When you open an EPUB book:
- Upload-time parsing — the book's spine, table of contents, and sidebar HTML are extracted & persisted
- SW interception — requests to
/@epubs/are routed through the service worker - HTML Rewrite — a streaming WASM-based pipeline sanitizes each page (strips scripts, injects viewer CSS & JS)
- Client-side viewer — the injected script builds the sidebar, rewrites navigation links, and tracks reading position
- Markdown note reading & editing
- Full-text search across your library
- Knowledge graph linking notes & books
- Plugin system for custom format support
- Sync backend (optional, self-hosted)
Built with ❤️ using TypeScript, React, and the open web.