
Bookshelf
A self-hosted ebook library that runs on Cloudflare R2 or a local Node server, with in-browser EPUB and PDF readers and per-profile reading positions.


What is Bookshelf?
Bookshelf is a self-hosted library for the ebooks you already own. It is a single server-rendered application that lists the books in your collection, filters them through a search box, serves downloads, and reads them in the browser through dedicated EPUB and PDF readers. There is no database — everything is read from object storage, which means backups are just the storage bucket.
The app ships with two interchangeable storage providers: a Cloudflare Worker backed by R2 object storage, or a plain Node server backed by a directory on disk. The same code drives both — only the storage adapter changes.
Key features
- One-page shelf. Books appear as a single server-rendered grid with covers, filterable through a search box and a Continue button that jumps straight back into the book being read.
- In-browser readers. EPUB and PDF each have their own reader. EPUB renders as a paginated reader in the browser; PDF is served with a native-style viewer.
- Profiles. Each reader picks a profile from a switcher, and reading positions are stored per profile so housemates or family members do not overwrite each other.
- Two storage providers. Cloudflare R2 via a Cloudflare Worker, or a local filesystem via a Node server. Docker is supported for the Node path.
- No database. The library is regenerated from the source files each time the sync tool runs, so there is nothing to migrate or back up beyond the storage itself.
- Public-domain demo.
npm run demopopulates the library with nine generated public-domain titles so the shelf can be tested or screenshotted without supplying your own ebooks.
Self-hosting
The fastest path is Docker: put EPUB and PDF files in a books/ directory and run docker compose up. The image includes the cwebp and pdftoppm image tools so covers come out right without installing anything on the host. A named library volume holds the published books, profiles, and reading positions — it is the only thing to back up.
Without Docker, Bookshelf runs on Node 24 or newer on any Unix-like system. Set bookshelf.config.json to point at a directory, run npm run sync -- --create, then npm start.
On Cloudflare, run npm run sync -- --create against an R2 bucket, then npm run deploy to ship the Worker. The repo includes checked-in wrangler.jsonc and bookshelf.config.json that need to agree about which bucket holds the library — the sync tool checks this before uploading.
A BOOKSHELF_READ_ONLY=1 environment flag tells a public instance to stop accepting writes while continuing to serve, useful for sharing a library without exposing the management interface.
How it compares to Kindle and Scribd
Kindle ties your ebook library to an Amazon account, syncs reading positions through Amazon’s servers, and requires the Kindle app or a Kindle device to read. Scribd does the same kind of thing through a subscription: a centralized catalog and reading positions hosted on Scribd’s servers, reachable from any device with an account. Bookshelf runs the same library-and-reader flow on hardware you control — the storage bucket (local or R2) holds the books, the in-browser reader replaces the vendor app, and reading positions are stored per profile in that same storage. Books you already own in EPUB or PDF can be dropped straight in. The trade-off is the things the paid services get for free — there is no built-in authentication, so anyone who can reach the app can read the whole library; running it as a public service means putting it behind your own access control, and there is no equivalent of the subscription catalogs that Kindle Unlimited or Scribd offer.
Categories:
Build with:
Frequently Asked Questions
Which platforms does Bookshelf run on?
Bookshelf is a web app — the reader and the shelf are both server-rendered pages reached through a browser, so any modern browser on Linux, macOS, Windows, iOS, or Android works. The server side runs on Node 24 or newer on Unix-like systems, or as a Cloudflare Worker backed by R2 object storage.
What ebook formats does Bookshelf support?
EPUB and PDF. Each format has its own reader in the browser — EPUB is rendered as a paginated reader, PDF is served through a PDF viewer — and covers are generated automatically. There is no support for DRM-protected files, so books need to be in their non-DRM EPUB or PDF form to be added to the library.
Does Bookshelf have authentication?
No. Anyone who can reach the app can read and download the whole library and pick any profile. Profiles are intended to keep housemates’ bookmarks separate, not to restrict access. For a public deployment you are expected to put Bookshelf behind your own access control or on a trusted network. Setting BOOKSHELF_READ_ONLY=1 stops writes while continuing to serve.
Can I import existing ebook libraries into Bookshelf?
Yes. Drop EPUB or PDF files into the books/ directory, run npm run sync (or docker compose run --rm sync), and the shelf is regenerated from those source files. The sync tool builds a library/ tree and publishes it to the configured storage. There is no importer for Kindle, Apple Books, or Google Play Books libraries — you copy the EPUB/PDF files themselves.
How does Bookshelf handle reading positions and backups?
Reading positions and profiles are stored alongside the books in the storage backend — on the R2 bucket when deployed to Cloudflare, or in the library volume on the filesystem when running locally. That means a backup of the bucket or the volume is a full backup of the app’s state. Restoring is just restoring that storage.
Repository details
Updated 8/25/2026, 11:00:15 AM
View Repository



