Self-hosted service
bookorbit/bookorbit avatar
bookorbit/bookorbit

BookOrbit: a self-hosted reading platform that syncs Kobo, KOReader and the web

BookOrbit: Your Reading Space

4,342 stars269 forksTypeScriptAGPL-3.0

At a glance

What is it?
BookOrbit is an AGPL-3.0, TypeScript and NestJS library server for ebooks, PDFs, audiobooks and comics. Its differentiator is three-way progress and annotation sync between a Kobo device, KOReader and its own web reader, and that is also where the operational cost sits.
Who is it for?
Adopt BookOrbit if you already read across a Kobo, KOReader and a browser and you are willing to run Postgres plus the app yourself; the sync and the annotation merge are the reason to pick it over a plain OPDS server. Do not adopt it if you want a single static binary or if you cannot expose an APP_URL that your devices can reach, because the sync design depends on that reachability.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem BookOrbit picks: three reading surfaces, three sets of bookmarks

Most self-hosted library servers stop at serving files. You get an OPDS endpoint, a download, and whatever your reading app does with it. Progress then lives wherever you happened to read: the Kobo keeps its own position, KOReader keeps a sidecar file, and a browser reader keeps a third record. BookOrbit targets that split directly. The README states that progress, highlights and reading status move between the web reader, a Kobo and KOReader, and that annotations from all three merge into one searchable hub. The intended user is someone with an existing book collection and more than one device, not someone looking for a storefront. It also carries the parts a household needs: multi-user accounts with per-user permissions and isolated reading data, and OIDC login through Authentik, Keycloak or Authelia. The feature list is wide (statistics, achievements, Send-to-Kindle, outbound sync to Hardcover, Readwise and StoryGraph), which tells you the project is aiming at the whole reading workflow rather than one slice of it.

How the sync actually works, and why Postgres is not optional

The stack is a NestJS server in TypeScript with a Vue frontend, and the Docker quick start provisions three directories: books, data/app and data/postgres. That last one is the tell. Reading state is not stored as files next to your books; it lives in a database, and the sync feature is a reconciliation problem over that database. A Kobo talks to the server through its own sync protocol, KOReader talks through a plugin that the README describes as an on-device catalog browser with search, download, status and rating management, and the web reader writes to the same records. The merge is bidirectional and, per the README, includes deletions, which is the detail worth pausing on: a highlight removed on one surface is expected to disappear on the others. The KOReader plugin is the piece that does the most work here, because it is both a catalog client and a sync client. Metadata is a separate pipeline with 14 named providers (Google Books, Open Library, Amazon, Goodreads, Kobo, Hardcover, Audible, Audnexus, Libro.fm, iTunes, ComicVine, RanobeDB, Aladin, Lubimyczytać), and cover art is sourced separately from iTunes, DuckDuckGo and AudiobookCovers. That separation matters when a match goes wrong: fixing a title match and fixing its cover are two different operations.

Getting it running: the four env values that decide whether it works

The README gives a four-command Docker quick start. You create a directory, make books, data/app and data/postgres, then pull .env.example and docker-compose.yml from the main branch. Four values are described as required. APP_URL is the URL you open in the browser, BOOKS_HOST_PATH is the folder on your server holding the book files, and then POSTGRES_PASSWORD, JWT_SECRET and SETUP_BOOTSTRAP_TOKEN, each with a suggested openssl rand invocation of a different length (hex 24, hex 32, hex 16). SETUP_BOOTSTRAP_TOKEN is a one-time setup wizard token, so it is consumed during first run rather than used at every boot. The README also flags a NAS case where the book folder is owned by a different user, and the text is truncated at that point, so I cannot tell you what the recommended ownership or UID mapping is. Treat that as something to check in the full README before you start, because a permissions mismatch on BOOKS_HOST_PATH is the kind of failure that shows up as an empty library rather than an error message. There is a live demo with a sample public-domain library, and the README notes that some administrative features are limited there, so the demo is useful for judging the reader and the interface, not the sync configuration.

Where it will not fit: single-user readers and appliance-style deployments

The obvious limitation is the shape of the deployment. BookOrbit is a server with a database, a frontend, a setup wizard and an OIDC integration surface. If your requirement is one binary that indexes a folder and serves OPDS, this is more moving parts than you need, and the extra parts are the ones that break. The sync design also assumes reachability: your Kobo and your KOReader device have to be able to reach APP_URL, which means a hostname or address that resolves from your LAN (and from outside it if you read while travelling). Get that wrong and the web reader still works while the device sync silently does not. The metadata layer is a second place to expect friction. Fourteen providers plus three separate cover sources means matching is a heuristic, and the README does not describe a conflict-resolution rule for when two providers disagree on a title or an author. On the maintenance side, the release cadence is visible in the supplied material: v2.7.0, v2.8.1 and v2.9.0 shipped within roughly three weeks of each other in August and September 2026. That is a fast-moving project, and fast releases on a schema-backed server usually mean migrations. Plan for backups of the Postgres volume, not just the books directory.

The alternative to compare against: Calibre-Web and plain OPDS

The realistic alternative for most people evaluating BookOrbit is Calibre-Web, which serves a Calibre library over the web with OPDS and a browser reader. The difference is architectural rather than cosmetic. Calibre-Web treats the Calibre database as the source of truth and reads from it; the library is a file you manage on the host. BookOrbit owns its own Postgres database and treats the book folder as content, with reading state, annotations and user accounts living in the database. That is why BookOrbit can merge highlights from three sources and Calibre-Web, as commonly deployed, cannot: there is no shared state store to merge into. The trade is that you now have a database to back up, migrate and keep consistent with the files. If you already run Calibre and are happy with it, BookOrbit is not a drop-in replacement, it is a second system with its own copy of the state. If you run no library server at all and only want OPDS for a reading app, an OPDS-capable server is a smaller commitment than either.

Licence and upgrade cost under AGPL-3.0

BookOrbit is AGPL-3.0, stated in the README and in the repository licence badge. For self-hosting that is unremarkable: you run it, you keep your modifications to yourself if you are not offering it to others over a network. The clause to be aware of is the network one. AGPL-3.0 extends the source-availability obligation to users who interact with a modified version over a network, so if you fork BookOrbit, change it, and let other people log in, the licence expects those users to be offered the corresponding source. That is a description of the licence text, not legal advice; get counsel if you plan to run a modified instance for anyone outside your household. Upgrade cost is the other axis. With three releases in about three weeks and a Postgres-backed schema, the practical routine is: snapshot the database volume and the books folder, pull the new image, and be ready to read the release notes for migration steps. The README does not document a rollback procedure, so the snapshot is your rollback.

What to verify before you migrate a real library

Start on the demo to judge the web reader, the annotation hub and the statistics screens, since the README says the demo carries a public-domain sample library and limits some admin features. Then stand up a throwaway instance with the four required env values and a small folder of test books, and check the two things the README cannot check for you. First, device sync: confirm your specific Kobo model and your KOReader version complete a round trip, because the README describes three-way sync as a capability, not as a per-model compatibility list. Second, identity: if you run Authentik, Keycloak or Authelia, complete a login through the setup wizard before you invite other users, since OIDC misconfiguration tends to surface at the moment a second account is created. Only after both pass should you point BOOKS_HOST_PATH at the real collection, and when you do, keep the Postgres volume in the same backup job as the books. They are two stores, and restoring one without the other gives you files with no progress or progress with no files.

Editorial conclusion

Adopt BookOrbit if you already read across a Kobo, KOReader and a browser and you are willing to run Postgres plus the app yourself; the sync and the annotation merge are the reason to pick it over a plain OPDS server. Do not adopt it if you want a single static binary or if you cannot expose an APP_URL that your devices can reach, because the sync design depends on that reachability. Before committing, verify three things on your own hardware: that your Kobo model is handled by the sync path, that the OIDC provider you actually run (Authentik, Keycloak or Authelia) completes a login against the setup wizard, and that a restore of the Postgres volume plus the books folder brings back both files and progress, since those are two separate stores.

Official sources

  1. bookorbit/bookorbit on GitHub
  2. License: AGPL-3.0
  3. Project website
  4. README
  5. Releases
Community notes

Community notes