About this project
Tandem is a pre-release (0.1.0, no tagged releases yet) self-hosted project whose goal is stated plainly: read a book, listen to the same book, and never lose your place. A server runs in Docker alongside PostgreSQL and the web app, while a React PWA and a Kotlin/Jetpack Compose Android app act as thin clients. The server owns all stateful work — it scans ebook and audiobook volumes, extracts metadata and covers, pairs an ebook with its audiobook, runs a transcription queue, generates sync maps, and is the only writer of reading position. Clients read and write position through REST endpoints with JWT auth and keep only device-local caches.
The distinguishing capability is sentence-level handoff between formats. Switching from reading to listening (or back) lands on the sentence you were on rather than the start of the chapter, across devices. That requires a transcript: the audiobook is transcribed and aligned to the EPUB text. Whisper can run locally in a server image built with the optional local stack, or, by default, jobs are handed to a separate Jetson worker (faster-whisper; an Orin Nano 8 GB is the reference deployment, medium model by default). A transcription queue with retries, an off-hours window, and a transcript editor accompanies this; transcription is optional, and without it you still get a library and two readers but no cross-format sync.
Other described features include a library scanner with series grouping and automatic ebook/audiobook pairing, a PWA web reader/player with lock-screen controls (the iPhone story, since there is no iOS app), an Android reader/listener with offline downloads, background playback and Android Auto, multi-user accounts with roles and invite-only registration by default, opt-in integrations (Audiobookshelf, Google Books, Open Library metadata, and ACSM/Audible imports requiring a special image build), and nightly Postgres dumps plus cover snapshots restorable from the UI.
Deployment is via Docker Compose. The README is unusually explicit that secrets belong in files rather than environment variables (JWT key, Postgres password, Fernet credential-encryption keys under secrets/), that the server must run as a single process because the queue and schedulers are process-local, and that a fresh install creates a superadmin with a randomly generated password written to the log, forcing a reset on first login. A reverse-proxy setup requires setting FORWARDED_ALLOW_IPS and a hardened Caddyfile example is provided. Extensive environment-variable tables cover mandatory, optional, auth-throttle, upload-limit and sync-tunable settings; API docs (/docs, /redoc) are deliberately disabled in production.
Documented limitations are candid: EPUB only for sync (PDFs pair but never align; MOBI/AZW3 must be converted), audiobooks must be single files (multi-file rips are skipped, merge to .m4b first), one transcription at a time, no horizontal scaling, no iOS app, Android Auto untested on hardware, no crash reporting anywhere, recently landed download/streaming paths, and nothing in any app store. The project is described as a single-maintainer effort in daily use with a real test suite but limited exposure to hardware and library layouts other than the author's.
Comments
0 Rating appears after 10 ratings
Sign in to join the discussion.