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, DeepInfra and OpenAI-compatible servers, the Replicate client, and Speech SDK for its hosted services.
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, with a port of Misaki and compromise for pronunciation
- Word timing: 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/)