Self-Hosted Text-to-Speech Reader

Voice AI Tools

A document reading-aloud reader: upload EPUB, PDF, DOCX, TXT or Markdown, have the content read aloud with speech synthesis with the sentence being read marked, and export a whole book as an M4B or MP3 audiobook. The Kokoro model used for speech synthesis runs inside the container on the CPU and needs no key. You bring it up on your own machine with Docker Compose, the initial admin password is generated at random by a script, and sign-up is off by default. Derived from a frozen snapshot of an open-source project under the MIT licence; the delivery adds a Dockerfile that builds the image from source, a single-service orchestration file, a password generation script and a quick-start guide in Traditional Chinese.

SubscriptionUS$49 per month
Last run2026-11-02
In practice
Readiness3 / 5
What you need
Few changes needed4 / 5

Who it is for

Individuals and families who want their documents and ebooks read to them, with the documents and the audio kept on their own machine.

How to start

$ sh scripts/quickstart/init-env.sh
$ docker compose up -d --build

Browse the files

Files in the product repository at the pinned commit. A few house files are left out of the zip.

File overview1,810 paths
▸desktop16
.gitignore
package.json
pnpm-lock.yaml
pnpm-workspace.yaml
runtime-binaries.json
scripts/
src/
▸docs-site684
.gitignore
custom.css
docs/
docusaurus.config.ts
package.json
pnpm-lock.yaml
pnpm-workspace.yaml
sidebars.ts
static/
tsconfig.json
…
▸examples1
openreader-seed.json
▸packages343
bootstrap/
compute-worker/
database/
runtime-config/
tts/
▸packaging8
download.mjs
ffmpeg/
kokoro-onnx/
▸public4
acknowledgements.json
demo/
web-app-manifest-192x192.png
web-app-manifest-512x512.png
▸quickstart1
openreader-seed.json
▸scripts15
acknowledgements/
build-changelog-feed.mjs
check-compute-boundary.mjs
check-install-profile.mjs
check-next-server-bundle.mjs
check-route-error-responses.mjs
collect-acknowledgements.mjs
quickstart/
▸src487
app/
components/
contexts/
hooks/
instrumentation.node.ts
instrumentation.ts
lib/
middleware.ts
types/
▸tests199
e2e/
files/
unit/
▸v511
AUDIO_STARTUP_AND_EXPORT_RELIABILITY_PLAN.md
AUTHENTICATION_PLAN.md
CLEANUP_PLAN.md
COMPUTE_RATE_LIMITING_PLAN.md
DESKTOP_SHELL.md
DESKTOP_SINGLE_OWNER.md
PLAYBACK_ARCHITECTURE.md
PLAYBACK_INTERACTION_RELIABILITY_PLAN.md
READER_READINESS_STATE_MACHINE.md
TEST_MIGRATION_PLAN.md
…
▫AGENTS.md
▫ATTRIBUTION.md
▫Dockerfile
▫LICENSE
▫LICENSE-99LL.md
▫PRODUCT.md
▫QUICKSTART.md
▫README.md
▫SECURITY.md
▫compose.yaml
▫delivery-manifest.txt
▫empty-module.ts
▫eslint.config.mjs
▫next.config.ts
▫package.json
▫playwright.config.ts
▫pnpm-lock.yaml
▫pnpm-workspace.yaml
▫postcss.config.mjs
▫tailwind.config.ts
▫tsconfig.json
▫vercel.json
▫vitest.config.ts
▫Config and hidden files 18

Latest passing run

Clone → Checkout → Toolchain → Build images → Reader sign in and documents

Pre-purchase Disclosure

What you are buying

A self-hosted document reading-aloud reader: upload EPUB, PDF, DOCX, TXT or Markdown, have it read aloud with speech synthesis, and export an audiobook. The speech synthesis runs inside the container on the CPU and needs no key.

Derived from an open-source project under the MIT licence, and not the original project itself. Our work: a Dockerfile that builds the image from source, an orchestration file, a password generation script and a quick-start guide in Traditional Chinese.

Delivery is a frozen snapshot: one zip, taken from the product repository at revision 7b25a2e.

Known limitations

  • The built-in voices speak only English, Spanish, Hindi, Italian and Brazilian Portuguese
  • The built-in voices cannot read Chinese, and reading a Chinese document aloud needs an external speech service
  • Before the first reading aloud, the speech model and pronunciation data are downloaded from the network, about 320 MB
  • Word-by-word highlighting and PDF layout analysis need two more models downloaded, and their size was not measured
  • Connecting an external speech service needs that service’s key of your own, and the text to be read aloud is sent to that service
  • The service serves plain HTTP on ports 3003 and 8081 of the local machine; TLS and a reverse proxy are yours to bring
  • The address must use 127.0.0.1, and using localhost instead prevents signing in properly
  • The interface is in English
  • Sending mail is not enabled, so a forgotten password cannot be reset by mail
  • Sign-up is off by default, and adding an account needs the administrator to open sign-up first
  • The data lives in a Docker named volume, and docker compose down -v deletes all of it
  • The first start builds the image from source, fetching from registries, apt and package repositories during that time
  • Pinned to the delivered snapshot; it does not follow upstream.

The liability cap, the scope of what is promised and the statutory floor are governed by the Terms of Service.

Vetting record

Everything below was checked against the pinned commit 555b970. Every verdict carries its full reasoning, an evidence link and the checker; failures are published, not hidden — do not take our word for it, verify it yourself.

5 PASS0 WARN0 FAIL

Source ReviewPASS

Execution surface of the delivery reviewed item by item. Our own additions were read line by line: compose.yaml (ports 3003 and 8081 are bound to 127.0.0.1 only and the built-in storage port 8333 is not published; it refuses to start when the sign-in secret, the playback signing secret or the admin credentials are missing; the data is in a named volume; the first-start settings file is mounted read-only), quickstart/openreader-seed.json (sign-up closed, guests off, speech from the built-in local Kokoro) and scripts/quickstart/init-env.sh (openssl generates random values, .env is mode 600, an existing .env is not overwritten). The Dockerfile is upstream’s own file with only the base images pinned by digest and fixed in version, and was also read line by line. The upstream TypeScript source was not read file by file; the basis is the MIT licence and container isolation.

Evidence is in our private repository (not publicly accessible):https://github.com/dev-zillio-cc/dsp-049-text-to-speech-reader/blob/7b25a2e3b0224aef9041a137c75de7b83870ca1b/compose.yamlChecked in 2026Checked by claude-code build-product session
Script SafetyPASS

The scripts on the buyer’s delivery path were each inspected: init-env.sh is ours (read line by line); the build goes through the Dockerfile (read line by line: pnpm at a given version installing from the lock file, the third-party licence list tool run at a given version, the SeaweedFS and NATS executables taken from fixed images, ffmpeg downloaded by upstream’s fetch script and verified by SHA-256, and a SeaweedFS licence text file downloaded at build time, with no download piped straight into a shell); the ffmpeg fetch script and the upstream start-up program the container starts through are upstream’s own files, not read line by line.

Evidence is in our private repository (not publicly accessible):https://github.com/dev-zillio-cc/dsp-049-text-to-speech-reader/blob/7b25a2e3b0224aef9041a137c75de7b83870ca1b/DockerfileChecked in 2026Checked by claude-code build-product session
RecencyPASS

This product is a frozen snapshot and does not follow upstream: the upstream source is pinned to the main-line revision taken on the day the product repository was created (see the evidence link), and the product repository is that snapshot plus our own commits.

Evidence ↗Checked in 2026Checked by claude-code build-product session
LicensePASS

SPDX:LicenseRef-99LL-Product

Upstream LICENSE was checked word for word (the evidence link points at the file itself at the pinned version and matches the copy inside the product repository): the standard MIT text, copyright holder Richard Roberson. It allows commercial use, modification, derivative works, redistribution and sale; the duty is to keep the copyright notice and licence text (LICENSE and ATTRIBUTION.md ship in the zip); upstream has no NOTICE file. The decision does not rest on GitHub’s licence field. For the product as a whole the 99LL product licence template is attached: upstream’s LICENSE is kept as it is and LICENSE-99LL.md is added as the sale and liability terms for the part we built, with spdx recorded as LicenseRef-99LL-Product.

Evidence ↗Checked in 2026Checked by claude-code build-product session
Dependency LicensesPASS

This records the declared side, not a scan result: the Node dependencies are declared in package.json and pnpm-workspace.yaml and locked by pnpm-lock.yaml, and the packages themselves are fetched from their own repositories when the buyer builds; the image also contains SeaweedFS, NATS, ffmpeg and LibreOffice, and the base images and system packages come from a registry and apt; the speech model and pronunciation data are downloaded from the network by the buyer’s machine at the first reading aloud and are not in the delivery. The licences of these dependency trees, third-party components and models were not scanned item by item. Upstream has no submodule and no third-party dataset was copied in (see ATTRIBUTION.md).

Evidence is in our private repository (not publicly accessible):https://github.com/dev-zillio-cc/dsp-049-text-to-speech-reader/blob/7b25a2e3b0224aef9041a137c75de7b83870ca1b/ATTRIBUTION.mdChecked in 2026Checked by claude-code build-product session
HEALTH VERIFIED

Last verified passing: 2026-11-02

Subscribe for everything
US$49/ monthwas US$99

A subscription unlocks the whole catalogue; you do not buy this one separately.See what is included

Sign in with Google first; if you are signed out you will be sent to the sign-in page. Your subscription is billed to that same email address.

Already subscribed? This downloads straight away. Otherwise you are sent to the pricing page, or to sign in first.