openreader/README.md
Richard R 6089d2c445 chore(db): move drizzle scripts and update commands
Relocate migration scripts to `drizzle/scripts`, update `start` and
`migrate`
to use the new path, and add a `generate` script for contributors.
Update README migration guidance for SQLite vs Postgres workflows.

BREAKING CHANGE: remove `migrate:force` and change migration script
paths; consumers relying on `scripts/migrate*.mjs` or `pnpm
migrate:force` must update to the new commands.
2026-01-27 17:46:29 -07:00

14 KiB
Raw Blame History

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, startup migrations target Postgres
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.

    Generating migrations (contributors):

    • pnpm generate generates migrations for both SQLite and Postgres (requires POSTGRES_URL).

    Manual Drizzle Kit runs:

    • SQLite migrate: npx drizzle-kit migrate --config drizzle.config.sqlite.ts
    • Postgres migrate: npx drizzle-kit migrate --config drizzle.config.pg.ts
    • SQLite generate: npx drizzle-kit generate --config drizzle.config.sqlite.ts
    • Postgres generate: npx drizzle-kit generate --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.