* Adjusted safe area padding, touch target sizes, and fullscreen behavior across mobile devices. * Measured reader bar height dynamically to prevent UI overlaps during orientation changes. * Refined pointer and tap gesture tracking to prevent accidental triggers. Signed-off-by: Chmouel Boudjnah <chmouel@chmouel.com> |
||
|---|---|---|
| .github | ||
| cmd/liseur-sync | ||
| docs | ||
| internal | ||
| scripts | ||
| tools/reader | ||
| .gitignore | ||
| .golangci.yml | ||
| .ko.yaml | ||
| .pre-commit-config.yaml | ||
| .reflex.conf | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| compose.yaml | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| liseur-sync.example.toml | ||
| Makefile | ||
| README.md | ||
| SECURITY.md | ||
liseur-sync
Self-hosted server for book libraries and reading-position synchronization.
liseur-sync is the companion server for Liseur. It also provides a kosync-compatible API for KOReader.
The server is a single Go binary with SQLite by default, optional PostgreSQL, and multi-user support.
Interfaces
liseur-sync provides:
- reading-position synchronization using full locators
- a native REST API
- a kosync-compatible API for KOReader
- OPDS 1.2
- EPUB library indexing and search
- EPUB upload and deletion for writable folders
- a browser based EPUB reader that supports offline reading.
- per-user reading statistics and sessions
- per-user series claims
API documentation is available in docs/openapi.yaml.
Client implementation notes and the synchronization protocol are documented in docs/integrating.md.
Reading synchronization
Reading-position updates are stored as an append-only log rather than replacing the previous position.
This allows the server to resolve updates from multiple devices without an older client blindly replacing newer state. The same history is used to derive reading sessions and statistics.
Book identity is independent of its filesystem path. Clients can resolve books using content and metadata identifiers, including hashes, before exchanging reading state.
Reader preferences — typeface, theme, margins and the like — sync too, as a small map of opaque strings per account, so a second device does not have to be set up from scratch. Unlike positions, these resolve by last-writer-wins on the time the reader made the change.
Library
liseur-sync can index either:
- a directory containing EPUB files
- a Calibre library using
metadata.db
Plain directories derive series information from their directory structure. Calibre libraries use metadata.db as the catalog source.
Catalogs are exposed through the web UI, REST API, and OPDS.
Folder access
Folders are granted to accounts individually. Adding a folder does not automatically make it visible to every account.
From the CLI:
liseur-sync admin add-folder -assign alice Shelf /srv/books
Folders can also be configured under:
Settings > Administration > Folders
Account folder grants are managed under:
Settings > Administration > Users
Writable folders
Folders are read-only by default.
Uploads and deletions are only allowed for folders explicitly configured to accept uploads:
liseur-sync admin folder-uploads <folder-id> on
For API clients:
library-uploadpermits adding books to writable folderslibrary-deletepermits removing books from writable folders
These are separate token scopes.
Deleting through the web UI requires an administrator account.
A folder that does not accept uploads remains read-only: the server indexes its contents but does not add or remove files from it.
See:
Web reader
liseur-sync includes a browser-based EPUB reader.
The reader uses the same synchronization API as other clients, so reading state is shared with Liseur, KOReader, and other compatible clients.
When another device has read further, the reader offers to continue there, naming both pages, how long ago the other device was there, and the passage it had on screen. The same comparison can be asked for at any time with the sync button in the reader bar (s), which shows both positions and offers to take the other one, keep this page, or cancel and change nothing. The library and the offline shelf refresh on a pull-down, or with their refresh button: pending reading is delivered first, then the page is redrawn. See ADR-0040.
EPUB content is unpacked and rendered without exposing publisher files through normal application routes. Scripts embedded in EPUBs are not executed.
The reader design and security model are documented in ADR-0007, including support for running the reader on a separate hostname.
Offline PWA
Liseur-sync's web UI ships as a PWA that lets you read books offline. From the library, choose Save offline for each book you want to carry, then install the site via your browser's "Add to Home Screen" option (Safari, Chrome, etc.). The installed app opens downloaded books without a network connection and keeps positions, reading sessions, highlights and notes locally until it can reconnect.
Installation
Install script
The installer supports Docker and rootless Podman.
curl -fsSL https://raw.githubusercontent.com/chmouel/liseur-sync/main/scripts/install.sh | bash
Alternatively:
git clone https://github.com/chmouel/liseur-sync.git
cd liseur-sync
scripts/install.sh
To install a specific version:
LISEUR_VERSION=vX.Y.Z scripts/install.sh
The installer configures the database, starts the server, and creates the initial account.
Docker Compose
SQLite:
docker compose --profile sqlite up -d
Bundled PostgreSQL:
docker compose --profile postgres up -d
External PostgreSQL:
docker compose --profile external up -d
Build from source
go build ./cmd/liseur-sync
./liseur-sync serve
Initial setup
The web interface is available at:
/ui/
When the database contains no accounts, the setup page creates the initial administrator account and can watch a first folder of books in the same step.
Users, folders, API tokens, folder grants, and reader pairing can be managed from the administration interface or with the admin CLI.
Deployment details, including TLS, KOReader pairing, Calibre integration, watched folders, and backups, are documented in docs/deployment.md.
Client integration
Liseur uses the native API.
Protocol and synchronization details:
OpenAPI specification:
Security
Security issues should be reported according to SECURITY.md.
Do not report security vulnerabilities through public GitHub issues.
License
MIT.
The screenshots use public-domain editions from Standard Ebooks and are generated by scripts/screenshots.sh.



