No description
Find a file
Richard R 297752e83e fix(db): select drizzle config for migrations
Add dedicated Drizzle config files for sqlite and postgres and generate
new migration outputs for each dialect.

Update migrate scripts to load env files and auto-pick the correct
config unless explicitly provided, and tighten API auth handling by
using shared auth context helpers and enforcing userId checks when auth
is enabled.
2026-01-27 16:53:58 -07:00
.github ci: enhance docker publish workflow for multi-arch support 2026-01-19 20:58:47 -07:00
drizzle fix(db): select drizzle config for migrations 2026-01-27 16:53:58 -07:00
examples feat(tts): add smart sentence continuation 2025-11-14 12:00:03 -07:00
public update(auth): enhance rate limiting with device/IP backstops and improve UI 2026-01-25 14:38:31 -07:00
scripts fix(db): select drizzle config for migrations 2026-01-27 16:53:58 -07:00
src fix(db): select drizzle config for migrations 2026-01-27 16:53:58 -07:00
tests refactor(auth): consolidate authentication contexts and enhance rate limit UI integration 2026-01-25 11:12:19 -07:00
.gitattributes Fix check mark in SettingsModal 2025-02-11 21:31:11 -07:00
.gitignore Add editable page number in PDF navigator view, to make it much easier to jump to specific pages 2025-06-20 08:32:53 +02:00
Dockerfile feat(db/auth): migrate auth storage to Drizzle and add claimable data flow 2026-01-26 17:01:36 -07:00
drizzle.config.pg.ts fix(db): select drizzle config for migrations 2026-01-27 16:53:58 -07:00
drizzle.config.sqlite.ts fix(db): select drizzle config for migrations 2026-01-27 16:53:58 -07:00
empty-module.ts First push 2025-01-18 04:58:57 -07:00
eslint.config.mjs First push 2025-01-18 04:58:57 -07:00
LICENSE Initial commit 2025-01-18 00:36:14 -07:00
next.config.ts feat(auth): add user authentication and rate limiting 2026-01-24 17:36:11 -07:00
NOTICE.txt docs: add third-party license notices 2026-01-15 11:04:59 -07:00
package.json fix(db): select drizzle config for migrations 2026-01-27 16:53:58 -07:00
playwright.config.ts chore(config): ignore unit tests in firefox and webkit browsers 2026-01-21 14:42:13 -07:00
pnpm-lock.yaml feat(db/auth): migrate auth storage to Drizzle and add claimable data flow 2026-01-26 17:01:36 -07:00
postcss.config.mjs First push 2025-01-18 04:58:57 -07:00
README.md fix(db): select drizzle config for migrations 2026-01-27 16:53:58 -07:00
tailwind.config.ts fix(tailwind): fix footer layout and tailwind config 2025-11-22 16:32:03 -07:00
template.env update(auth): enhance rate limiting with device/IP backstops and improve UI 2026-01-25 14:38:31 -07:00
tsconfig.json First push 2025-01-18 04:58:57 -07:00

GitHub Stars GitHub Forks GitHub Watchers GitHub Issues GitHub Last Commit GitHub Release

Discussions

📄🔊 OpenReader WebUI

OpenReader WebUI is an open source text to speech document reader web app built using Next.js, offering a TTS read along experience with narration for EPUB, PDF, TXT, MD, and DOCX documents. It supports multiple TTS providers including OpenAI, Deepinfra, and custom OpenAI-compatible endpoints like Kokoro-FastAPI and Orpheus-FastAPI

  • 🎯 Multi-Provider TTS Support
    • Kokoro-FastAPI: Supporting multi-voice combinations (like af_heart+af_bella)
    • Orpheus-FastAPI
    • Custom OpenAI-compatible: Any TTS API with /v1/audio/voices and /v1/audio/speech endpoints
    • Cloud TTS Providers (requiring API keys)
      • Deepinfra: Kokoro-82M + models with support for cloned voices and more
      • OpenAI API (): tts-1, tts-1-hd, and gpt-4o-mini-tts w/ instructions
  • 🛜 (Updated) Server-side Sync and Storage
    • (New) External Library Import enables importing documents to the browser's storage from a folder mounted on the server
    • (Updated) Sync documents between the browser and server to get them on other browsers or devices
  • 🎧 Server-side Audiobook Export in m4b/mp3, with resumable, chapter-based export and regeneration
  • 📖 Read Along Experience providing real-time text highlighting during playback (PDF/EPUB)
    • (New) Word-by-word highlighting uses word-by-word timestamps generated server-side with whisper.cpp (optional)
  • 🧠 Smart Sentence-Aware Narration merges sentences across pages/chapters for smoother TTS
  • 🚀 Optimized Next.js TTS Proxy with audio caching and optimized repeat playback
  • 🎨 Customizable Experience
    • 🎨 Multiple app theme options
    • ⚙️ Various TTS and document handling settings
    • And more ...

🐳 Docker Quick Start

Prerequisites

  • Recent version of Docker installed on your machine
  • A TTS API server (Kokoro-FastAPI, Orpheus-FastAPI, Deepinfra, OpenAI, etc.) running and accessible

Note: If you have good hardware, you can run Kokoro-FastAPI with Docker locally (see below).

1. 🐳 Start the Docker container

Minimal (no persistence, auth disabled unless you set auth env vars):

docker run --name openreader-webui \
  --restart unless-stopped \
  -p 3003:3003 \
  ghcr.io/richardr1126/openreader-webui:latest

Fully featured (persistent storage + server library import + KokoroFastAPI in Docker + optional auth):

docker run --name openreader-webui \
  --restart unless-stopped \
  -p 3003:3003 \
  -v openreader_docstore:/app/docstore \
  -v /path/to/your/library:/app/docstore/library:ro \
  -e API_BASE=http://host.docker.internal:8880/v1 \
  -e API_KEY=none \
  -e BETTER_AUTH_URL=http://localhost:3003 \
  -e BETTER_AUTH_SECRET=<paste_the_output_of_openssl_here> \
  ghcr.io/richardr1126/openreader-webui:latest

You can remove the /app/docstore/library mount if you don't need server library import. You can remove both BETTER_AUTH_* env vars to keep auth disabled.

Notes:

  • API_BASE should point to your TTS API server's base URL (if running Kokoro-FastAPI locally in Docker, use http://host.docker.internal:8880/v1).
  • BETTER_AUTH_URL should be your externally-facing URL for this app (for example https://reader.example.com or http://localhost:3003).
  • To enable auth, set both BETTER_AUTH_URL and BETTER_AUTH_SECRET generated with openssl rand -base64 32.
  • If you set POSTGRES_URL, the container will attempt to run migrations against it. Ensure the database is accessible.
Docker environment variables (Click to expand)
Variable Purpose Example / Notes
API_BASE Default TTS API base URL (server-side) http://host.docker.internal:8880/v1
API_KEY Default TTS API key none or your provider key
BETTER_AUTH_URL Enables auth when set with BETTER_AUTH_SECRET External URL for this app, e.g. http://localhost:3003 or https://reader.example.com
BETTER_AUTH_SECRET Enables auth when set with BETTER_AUTH_URL Generate with openssl rand -base64 32
POSTGRES_URL Use Postgres for auth storage instead of SQLite If set, run migrations manually (see note above)
GITHUB_CLIENT_ID Optional GitHub OAuth sign-in Requires GITHUB_CLIENT_SECRET
GITHUB_CLIENT_SECRET Optional GitHub OAuth sign-in Requires GITHUB_CLIENT_ID
Docker volume mounts (Click to expand)
Mount Type Recommended Purpose Example
/app/docstore Docker named volume Yes Persists server-side storage (documents, audiobook exports, settings, SQLite DB if used) -v openreader_docstore:/app/docstore
/app/docstore/library Bind mount (host folder) Optional + :ro Exposes an existing folder of documents for Server Library Import -v /path/to/your/library:/app/docstore/library:ro

To import from the mounted library: Settings → Documents → Server Library Import

Note: Every file in the mounted library is imported into the client browser's storage. Keep the library reasonably sized to avoid performance issues.

Visit http://localhost:3003 to run the app and set your settings.

2. ⚙️ Configure the app settings in the UI

  • Set the TTS Provider and Model in the Settings modal
  • Set the TTS API Base URL and API Key if needed (more secure to set in env vars)
  • Select your model's voice from the dropdown (voices try to be fetched from TTS Provider API)

3. ⬆️ Updating Docker Image

docker stop openreader-webui && \
docker rm openreader-webui && \
docker pull ghcr.io/richardr1126/openreader-webui:latest

🗣️ Local Kokoro-FastAPI Quick-start (CPU or GPU)

You can run the Kokoro TTS API server directly with Docker. We are not responsible for issues with Kokoro-FastAPI. For best performance, use an NVIDIA GPU (for GPU version) or Apple Silicon (for CPU version).

Kokoro-FastAPI (CPU)

docker run -d \
  --name kokoro-tts \
  --restart unless-stopped \
  -p 8880:8880 \
  -e ONNX_NUM_THREADS=8 \
  -e ONNX_INTER_OP_THREADS=4 \
  -e ONNX_EXECUTION_MODE=parallel \
  -e ONNX_OPTIMIZATION_LEVEL=all \
  -e ONNX_MEMORY_PATTERN=true \
  -e ONNX_ARENA_EXTEND_STRATEGY=kNextPowerOfTwo \
  -e API_LOG_LEVEL=DEBUG \
  ghcr.io/remsky/kokoro-fastapi-cpu:v0.2.4

Adjust environment variables as needed for your hardware and use case.

Kokoro-FastAPI (GPU)

docker run -d \
  --name kokoro-tts \
  --gpus all \
  --user 1001:1001 \
  --restart unless-stopped \
  -p 8880:8880 \
  -e USE_GPU=true \
  -e PYTHONUNBUFFERED=1 \
  -e API_LOG_LEVEL=DEBUG \
  ghcr.io/remsky/kokoro-fastapi-gpu:v0.2.4

Adjust environment variables as needed for your hardware and use case.

⚠️ Important Notes:

  • For best results, set the -e API_BASE= for OpenReader's Docker to http://kokoro-tts:8880/v1
  • For issues or support, see the Kokoro-FastAPI repository.
  • The GPU version requires NVIDIA Docker support and works best with NVIDIA GPUs. The CPU version works best on Apple Silicon or modern x86 CPUs.

Local Development Installation

Prerequisites

  • Node.js (recommended: use nvm)

  • pnpm (recommended) or npm

    npm install -g pnpm
    
  • A TTS API server (Kokoro-FastAPI, Orpheus-FastAPI, Deepinfra, OpenAI, etc.) running and accessible Optionally required for different features:

  • FFmpeg (required for audiobook m4b creation only)

    brew install ffmpeg
    
  • libreoffice (required for DOCX files)

    brew install libreoffice
    
  • whisper.cpp (optional, required for word-by-word highlighting)

    # clone and build whisper.cpp (no model download needed  OpenReader handles that)
    git clone https://github.com/ggml-org/whisper.cpp.git
    cd whisper.cpp
    cmake -B build
    cmake --build build -j --config Release
    
    # point OpenReader to the compiled whisper-cli binary
    echo WHISPER_CPP_BIN=\"$(pwd)/build/bin/whisper-cli\"
    

    Note: The WHISPER_CPP_BIN path should be set in your .env file for OpenReader to use word-by-word highlighting features.

Steps

  1. Clone the repository:

    git clone https://github.com/richardr1126/OpenReader-WebUI.git
    cd OpenReader-WebUI
    
  2. Install dependencies:

    With pnpm (recommended):

    pnpm i # or npm i
    
  3. Configure the environment:

    cp template.env .env
    # Edit .env with your configuration settings
    

    Auth is recommended for contributors and is enabled when both values are set:

    • Set BETTER_AUTH_URL to your local URL (default: http://localhost:3003)

    • Generate a BETTER_AUTH_SECRET and paste it into .env:

      openssl rand -base64 32
      

    Note: To disable auth, remove either BETTER_AUTH_URL or BETTER_AUTH_SECRET.

    Note: The base URL for the TTS API should be accessible and relative to the Next.js server

  4. Run auth DB migrations:

    • Production / Docker: Migrations run automatically on startup via pnpm start.

    • Development: Run explicitly:

      pnpm migrate
      

    Note: If you set POSTGRES_URL in .env, migrations will target Postgres instead of local SQLite.

    Manual Drizzle Kit runs:

    • SQLite: npx drizzle-kit migrate --config drizzle.config.sqlite.ts
    • Postgres: npx drizzle-kit migrate --config drizzle.config.pg.ts
  5. Start the development server:

    With pnpm (recommended):

    pnpm dev # or npm run dev
    

    or build and run the production server:

    With pnpm:

    pnpm build # or npm run build
    pnpm start # or npm start
    

    Visit http://localhost:3003 to run the app.

💡 Feature requests

For feature requests or ideas you have for the project, please use the Discussions tab.

🙋‍♂️ Support and issues

If you encounter issues, please open an issue on GitHub following the template (which is very light).

👥 Contributing

Contributions are welcome! Fork the repository and submit a pull request with your changes.

❤️ Acknowledgements

This project would not be possible without standing on the shoulders of these giants:

Docker Supported Architectures

  • linux/amd64 (x86_64)
  • linux/arm64 (Apple Silicon, Raspberry Pi, SBCs, etc.)

Stack

License

This project is licensed under the MIT License.