Stack
OpenReader is a pnpm workspace written in TypeScript. The architecture is described in the repository's v5/ documents.
| Package | Role |
|---|---|
| Root app | Next.js app: sign-in, library, reader, settings, API routes |
packages/compute-worker | Speech generation, alignment, PDF layout, previews, conversion, exports |
packages/tts | Provider clients shared by the app and worker |
packages/database | Drizzle schemas and migrations for SQLite and Postgres |
packages/bootstrap | Startup: configuration checks, migrations, and the embedded services |
packages/runtime-config | Configuration shared by the app and worker |
desktop/ | Electron shell for the desktop app (a separate project) |
App
- Framework: Next.js 15 (App Router) and React 19
- UI: Tailwind CSS 3, Headless UI,
react-dnd,react-dropzone,react-hot-toast - Data: TanStack Query; server-sent events for playback and job progress
- Readers: react-pdf and pdf.js for PDF, epub.js for EPUB, react-markdown with remark-gfm for Markdown and text
- Web import: Readability, Turndown, linkedom
- Text matching: cmpstr
- Sign-in: Better Auth
- Database: Drizzle ORM with SQLite (
better-sqlite3) or Postgres (pg) - Storage: AWS SDK v3 against embedded SeaweedFS or any S3-compatible service
- Logging: Pino
TTS providers
packages/tts uses the OpenAI SDK for OpenAI and OpenAI-compatible servers, the Replicate client, and direct bounded REST requests for Google AI Studio, Fish Audio and OpenRouter.
Compute worker
- Server: Fastify 5 with an OpenAPI contract; the app's client is generated from it
- Jobs: NATS JetStream work queues and key-value state
- Inference:
onnxruntime-nodewith@huggingface/tokenizers- Speech: Kokoro-82M, exported with its per-phoneme durations so local Kokoro times its own words, with a port of Misaki and compromise for English pronunciation, and tables learned from Kokoro's own readings of Tatoeba sentences for Spanish, Hindi, Italian and Brazilian Portuguese. Voice packs and pronunciation data download when their language is first used.
- Word timing for other providers: timestamped Whisper base and Whisper tiny.en
- PDF layout: PP-DocLayoutV3
- Documents:
pdfjs-distand@napi-rs/canvasto render pages,fast-xml-parserandjszipfor EPUB, headless LibreOffice for DOCX - Audio: FFmpeg, a pinned LGPL build in published images and the desktop app (
packaging/ffmpeg) - Exports and email:
archiver, Resend
The worker runs embedded in Docker, native and desktop installs, or as its own service. The app talks to it only over HTTP.
Desktop
Electron with electron-builder and electron-updater. It runs the same server and worker as the Docker image.
Tooling
- ESLint and TypeScript
- Vitest 4 for unit and integration tests
- Playwright for end-to-end tests in Chromium and WebKit
- Docusaurus for this site (
docs-site/)