Self-hosted service
booklore-app/booklore avatar
booklore-app/booklore

BookLore: a self-hosted library that wants to own your files

BookLore: A self-hosted, multi-user digital library with smart shelves, auto metadata, Kobo & KOReader sync, BookDrop imports, OPDS support, and a built-in reader for EPUB, PDF, and comics.

1,166 stars85 forksJavaAGPL-3.0

At a glance

What is it?
BookLore is a Spring Boot and Angular application that runs your ebook collection as a Docker service, with rule-based shelves, in-browser reading, Kobo and KOReader sync, and an OPDS endpoint. The interesting part is not the feature list but the line the README draws at local disks.
Who is it for?
Adopt BookLore if your book files sit on a local disk attached to the host running Docker, you want per-user shelves and progress rather than one shared library, and you accept that the app will rename and rewrite files in your /books volume. Do not adopt it if your library lives on a NAS, NFS, or SMB mount and you also want automatic metadata writing and file organization, because the README states those two things cannot both be true.
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 last received commits 3 days ago.
What is it written in?
Mainly Java, 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 gap between Calibre and a shared household library

Most self-hosted book setups start with Calibre and end with Calibre-Web bolted on top. That works for one person. It gets awkward the moment a second reader wants their own progress, their own shelves, and their own reading position without seeing the first person's annotations. BookLore targets exactly that second scenario. The README describes it as a self-hosted app that brings a collection under one roof, with individual shelves, progress, and preferences per user, plus local or OIDC authentication. The topics list on the repository confirms the stack: spring-boot, angular, oidc, opds. So the audience is a household or a small group that already runs Docker Compose, already has a MariaDB-shaped hole in their stack, and wants reading progress to follow them onto a Kobo or a KOReader install rather than staying locked in a browser tab. It is not aimed at someone who wants a desktop cataloguing tool, and it is not aimed at anyone whose books live on a NAS, which the README is unusually blunt about.

Spring Boot, MariaDB, and a watched folder

The architecture visible in the material is a two-container Compose stack. The application container is ghcr.io/booklore-app/booklore, built on Spring Boot, listening on port 6060, with an Angular front end served from the same process. It talks to a MariaDB 11.4.5 container over JDBC using the DATABASE_URL value, and it waits on a mariadb healthcheck (mariadb-admin ping) before starting. Three volumes define the data flow: ./data for application state, ./books for the library itself, and ./bookdrop for the import queue. BookDrop is the mechanism worth understanding. The README describes a four-step pipeline: files dropped into the watched folder are auto-detected, parsed, enriched with metadata from Google Books and Open Library, then queued for review before import. The word queued matters. Import is not silent; the README says you review and tweak before adding to the library. Metadata enrichment also draws on Amazon according to the features table, and the README notes that covers, descriptions, reviews, and ratings are all editable. Reading happens in the browser for EPUB, PDF, and comics, with annotations and highlights stored alongside progress. Device sync is offered three ways: a Kobo connection, KOReader progress sync, and an OPDS endpoint for any OPDS-compatible client. Magic Shelves are rule-based and dynamic, meaning membership is computed from rules and filters rather than assigned by hand, and full-text search sits over the collection.

Getting it running with Docker Compose

The README gives a complete two-file setup. Create a .env with APP_USER_ID, APP_GROUP_ID, TZ, DATABASE_URL, DB_USER, DB_PASSWORD, DISK_TYPE, DB_USER_ID, DB_GROUP_ID, MYSQL_ROOT_PASSWORD, and MYSQL_DATABASE. The example values are DATABASE_URL=jdbc:mariadb://mariadb:3306/booklore, DB_USER=booklore, DISK_TYPE=LOCAL, and MYSQL_DATABASE=booklore. Then create docker-compose.yml with the booklore service mapping port 6060:6060, the three volume mounts, and the mariadb service using image lscr.io/linuxserver/mariadb:11.4.5. Note the environment variable name mismatch that catches people: the .env file defines DB_USER and DB_PASSWORD, but the Compose file passes them into the container as DATABASE_USERNAME and DATABASE_PASSWORD. Both names appear in the README, and both are required. The healthcheck hits http://localhost:6060/api/v1/healthcheck with wget, on a 60 second interval, five retries, a 60 second start period, and a 10 second timeout. Launch with docker compose up -d, then open http://localhost:6060 and create the admin account. The README also states that metadata enrichment pulls from Google Books, Open Library, and Amazon, so outbound network access from the container is part of the deployment, not an optional extra.

The DISK_TYPE=NETWORK escape hatch and what it costs

This is the part of the README that deserves the most attention, because it is a genuine architectural boundary rather than a configuration preference. BookLore's file operations, which the README lists as metadata writing, file renaming, and file organization, are stated to be built for local file systems only. Network-attached storage, including NAS, NFS, SMB/CIFS mounts, and cloud-backed FUSE, is described as unsupported and untested, with the warning that mount options, latency, caching, and filesystem semantics can cause silent file corruption, incomplete writes, and missing files. The README goes further than most projects do: issues related to network storage will be closed without investigation. The supported path for network storage is DISK_TYPE=NETWORK, which disables all file write and reorganization features. Metadata then lives in the database only, and your files are never modified. That is a real trade-off, not a workaround. If your library is on a NAS, you keep your files untouched but you lose automatic metadata writing into the files themselves and you lose file organization. If you want those features, your books must be on a local disk. The README says the two cannot be combined. Anyone planning a deployment on a Synology share with SMB mounts should decide which half they are giving up before they start, because the project has already decided for them.

Where Calibre-Web fits better, and where it does not

Calibre-Web is the obvious alternative and the difference is structural rather than a feature checklist. Calibre-Web reads a Calibre metadata database and typically treats the Calibre library directory as the source of truth, with the desktop application remaining the place where serious cataloguing and conversion happen. BookLore inverts that. It has no dependency on Calibre, it stores its own metadata in MariaDB, and it manages the book directory itself when DISK_TYPE=LOCAL is set, renaming and organizing files as part of its own operations. That is why the network storage warning exists at all: a system that rewrites your files needs predictable filesystem semantics, and a system that merely reads them does not. The second difference is multi-user behaviour. BookLore is described as multi-user ready with individual shelves, progress, and preferences per user and OIDC authentication, which is a first-class concern rather than a bolt-on. If you are one person with an existing Calibre library and no interest in a database-backed catalog, Calibre-Web is a shorter path and will not touch your files. If you are several readers sharing a server and you want per-user progress plus Kobo and KOReader sync, BookLore's data model is built around that from the start.

Maintenance surface: three containers, a database, and AGPL-3.0

The upgrade path is docker compose pull followed by docker compose up -d, with the MariaDB data living in ./mariadb/config and the application state in ./data. Recent releases in the material are v2.3.1 on 2026-06-26, v2.3.0 on 2026-04-29, and v2.2.2 on 2026-04-14, which suggests a cadence of a few releases per quarter, and the default branch is develop, so the bleeding edge is not what the tagged images track. The maintenance cost is not the container count, it is the database. MariaDB is a second service with its own version, its own backup obligation, and its own upgrade path, and the README's Compose file pins lscr.io/linuxserver/mariadb:11.4.5 rather than a floating tag. Backing up ./data without backing up the MariaDB volume gives you a library whose metadata is gone. On licensing, BookLore is AGPL-3.0, copyright 2024 to 2026. The AGPL's network clause is the part that matters for anyone considering a modified deployment exposed to other users; if you fork it and run it as a service, the licence obligations differ from a permissive licence. That is a question for your own counsel, not something this article can settle, but it is worth knowing before you plan a derivative.

What the documentation does not tell you

Several things a reader would reasonably want to know are absent from the supplied material. There is no stated minimum RAM or CPU, no guidance on library size limits, and no description of how Magic Shelf rules are expressed, whether as a query builder in the UI or as a syntax you type. The README mentions full-text search but does not say whether it covers book text or only metadata fields, which is a large difference in indexing cost. The Kobo and KOReader sync sections are named in the feature table but the material does not describe the protocol, what happens on a sync conflict, or whether progress is resolved last-write-wins. The OPDS endpoint is mentioned without a path. The Amazon metadata source is listed without any note on API keys, rate limits, or whether it is scraping. None of this is a criticism of the project so much as a limit of what can be verified from the README, and anyone evaluating BookLore for a large library should read the documentation site rather than assume the feature table is the whole story. The one thing the README is unambiguous about is the network storage boundary, and that is the constraint most likely to decide whether BookLore fits.

Editorial conclusion

Adopt BookLore if your book files sit on a local disk attached to the host running Docker, you want per-user shelves and progress rather than one shared library, and you accept that the app will rename and rewrite files in your /books volume. Do not adopt it if your library lives on a NAS, NFS, or SMB mount and you also want automatic metadata writing and file organization, because the README states those two things cannot both be true. Before committing, verify three things in a disposable stack: that DISK_TYPE=LOCAL is what you actually want given the file operations it enables, that the healthcheck endpoint at /api/v1/healthcheck returns cleanly behind your reverse proxy, and that the MariaDB credentials in your .env are not the ChangeMe_BookLoreApp_2025! placeholders.

Official sources

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

Community notes