The self-hosted library that tends itself.
Drop in a book. Scriptorium imports it, converts it, finds its cover and metadata,
and puts it on your Kobo by the next sync. You just read.
Quick start Β· Demo Β· Features Β· Screenshots Β· Docs Β· Coming from CWA?
Most ebook servers are file browsers with a login page. Scriptorium is a library that keeps itself in order and a place you actually enjoy opening.
| Copy a file into one folder. Scriptorium imports it, converts it to the format your reader wants, fetches cover and metadata, catches duplicates and repairs EPUBs that Amazon would reject. All automatically. | Paste one line on your Kobo and your library, shelves and reading progress stay in step, with no cables and no Calibre desktop app. KOReader syncs progress and highlights too. |
| Every highlight from your e-reader on one page. A full-screen story of your year in books. Your Goodreads or StoryGraph history imported in a minute. | A clean, fast interface in light and dark, built for phones and installable as an app. Every reader can give it their own colours, from a ready-made theme to a hand-tuned palette. |
scriptorium-demo.mp4
One minute: importing a book, the library, Kobo and KOReader sync, reading statistics, highlights, your year in books and personal styles.
All you need is Docker with the Compose plugin. New to self-hosting? Start here: a friendly, step-by-step guide that assumes nothing.
mkdir scriptorium && cd scriptorium
curl -O https://raw.githubusercontent.com/MrColoo/scriptorium-library/main/docker-compose.yml
docker compose up -dOpen http://localhost:8083 and create your account: the first page asks for a username and a password, then a short tour shows you around.
Now drop an EPUB, PDF, MOBI or any other ebook into the ingest folder next to the compose file
and watch it appear in your library. Then connect your Kobo; it takes about
two minutes.
What's in docker-compose.yml
services:
scriptorium:
image: ghcr.io/mrcoloo/scriptorium-library:latest
container_name: scriptorium
environment:
- PUID=1000 # run `id -u` to find yours
- PGID=1000 # run `id -g` to find yours
- TZ=Europe/London
volumes:
- ./config:/config # settings, users, logs, backups
- ./ingest:/cwa-book-ingest # drop books here; files are removed after import
- ./library:/calibre-library # your Calibre library (created if empty)
ports:
- 8083:8083
restart: unless-stoppedAlready have a Calibre library? Point ./library at it. Scriptorium uses it as it is.
flowchart LR
A["π Drop a file<br/>into /ingest"] --> B["π Convert<br/>to KEPUB / EPUB"]
B --> C["π·οΈ Cover & metadata<br/>from 12 providers"]
C --> D["π§Ή Duplicates & EPUB fixes"]
D --> E["π Your library"]
E --> F["Kobo sync"]
E --> G["KOReader"]
E --> H["OPDS apps"]
E --> I["Email to Kindle<br/>& eReaders"]
E --> J["Read in the browser"]
Your books live in a standard Calibre library, so you can open it with Calibre desktop at any time. Nothing is locked in.
Automation
- Auto-import from a watched folder, with web upload too. Works on NFS/SMB shares.
- Conversion to your target format (KEPUB for Kobo, EPUB for everything else), plus a one-click run for the whole library.
- Metadata and covers from Google Books, Hardcover, Amazon, ComicVine, Kobo, DNB and more. Fields are only replaced when the new value is better.
- Duplicate detection with previews, merging and optional automatic resolution.
- EPUB fixer that repairs the small errors Send-to-Kindle rejects.
- Automatic backups of every original before it's touched.
Reading
- Kobo sync: books, shelves as collections, reading progress and a guided setup on your profile.
- KOReader sync plugin for Kindle, PocketBook, Android and Kobo: progress, highlights and reading statistics.
- Your devices, your choice: turn Kobo and KOReader on or off per user; progress shows where it came from.
- Continue reading on the home page, fed by your devices, with time left in each book.
- Built-in readers: EPUB with themes and typography settings, comics, PDF and plain text. The EPUB reader picks up where your Kobo or KOReader left off, and its highlights and reading time join the rest.
- OPDS catalogue for apps like KyBook, Moon+ Reader and Panels.
- Send to eReader by email, automatically for new books if you like.
Your reading life
- Your year in books: a full-screen story of your reading year (books, hours, authors, genres, streaks, your reading clock, the book you lived in, the line you kept) with a poster to save and share.
- Highlights: every passage and note from your Kobo, KOReader or the built-in reader on one page, searchable and exportable to Markdown for Obsidian, Notion or Readwise. Device highlights show in the built-in reader, browser highlights reach KOReader, and the home page opens with a passage of the day.
- Reading statistics: time read, streaks, a calendar of your year and your habits, shared between all your KOReader devices.
- Import from Goodreads or The StoryGraph: finished books with their dates, what you are reading and your want-to-read list, after a preview.
- More like this on every book page, ranked from your own library.
Library
- Shelves and smart shelves that fill themselves from rules (for example "unread sci-fi" or "added since June").
- Multi-user with permissions, per-user devices, LDAP, OAuth and generic OIDC sign-in.
- Reading statistics, and an activity log for administrators.
- 28 languages.
Interface
- Designed page by page, light and dark, fully usable on a phone with a bottom navigation bar.
- Installable app: add Scriptorium to your home screen, and send a book to the library with Share β Scriptorium from any app (needs HTTPS).
- What's new after every update, and an update button for administrators with the highlights of the next release.
- Personal styles: eleven themes, a "Surprise me" button and a palette editor, with a live preview.
- Security by default: a strict Content-Security-Policy with no inline scripts, CSRF on every action and a password change forced at first login. More
Home β what you're reading on your Kobo, something to discover, and the whole library. It follows your light or dark theme.
Your year in books β tap through your reading year, then save the poster
Highlights β from your Kobo and KOReader, grouped by book and chapter
On your phone β the same library, built for one hand
| Container path | What it holds |
|---|---|
/config |
app.db (users, settings, reading progress), cwa.db (automation settings, statistics), logs, profile pictures, backups in processed_books/. Back this up. |
/cwa-book-ingest |
Drop zone. Supported files are imported and then deleted from here. Copy finished files in; don't download into it. |
/calibre-library |
Your Calibre library (metadata.db and book folders). If it's empty, a new library is created. If there are several, the largest is used. |
/config/.config/calibre/plugins |
Optional: Calibre plugins used during conversion. |
| Variable | Default | Purpose |
|---|---|---|
PUID / PGID |
1000 |
Owner of the files written to your volumes. |
TZ |
UTC |
Time zone for schedules and timestamps, e.g. Europe/Rome. |
CWA_PORT_OVERRIDE |
8083 |
Port the web server listens on inside the container. |
HARDCOVER_TOKEN |
β | API key for Hardcover as a metadata provider (also settable in the UI). |
NETWORK_SHARE_MODE |
false |
true when the library or config live on NFS/SMB: safer SQLite settings, polling instead of inotify. |
CWA_WATCH_MODE |
inotify |
poll forces polling for new files. |
TRUSTED_PROXY_COUNT |
1 |
Number of reverse proxies in front of Scriptorium. |
DISABLE_LIBRARY_AUTOMOUNT |
false |
true skips automatic library detection at start-up. |
SCRIPTORIUM_DEFAULT_ADMIN |
false |
true gives a new installation the admin / admin123 account instead of the setup page, for automated installs. |
The configuration reference lists every variable and setting. Network shares and NAS setups are in the installation reference, and HTTPS and reverse proxies in Remote access.
docker compose pull && docker compose up -dWhen a new release is out, administrators get an update button in the top bar with its highlights
and this command. After updating, every user gets a short What's new. To pin a version, use a release tag such as
ghcr.io/mrcoloo/scriptorium-library:v1.0.0 instead of latest.
Everything that matters lives in two folders, config and library. Stop the container to get
a consistent copy:
docker compose stop
tar czf scriptorium-backup-$(date +%F).tar.gz config library
docker compose startTo restore, extract the archive in place of the two folders and start the container again. Updating and backups covers automatic backups, version pinning and moving to a new server.
Scriptorium is built on Calibre-Web-Automated v4.0.8 and reads and writes exactly the same data, so switching is an image swap:
- Back up your
configandlibraryfolders (how). - In your compose file, change only the image to
ghcr.io/mrcoloo/scriptorium-library:latest. Keep the volumes, ports and environment variables as they are. - Run
docker compose up -d.
What carries over, and what to know:
- Your data stays compatible. Scriptorium changes no existing table or column. It adds one
table to
app.dbfor your highlights, which CWA simply ignores. Users, shelves, smart shelves, reading progress and Kobo and KOReader sync state all carry over, and you can switch back the same way. - Your devices keep working. The Kobo sync address and the KOReader endpoint are unchanged. Download the KOReader plugin again if you want your KOReader highlights in Scriptorium.
- Personal styles are stored inside each user's existing view settings. CWA simply ignores them.
- Your instance title is kept. To show "Scriptorium" in the header, change it in Settings β Interface.
- Newer CWA releases that changed the database have not been tested. Keep your backup at hand.
Coming from plain Calibre-Web? See the installation guide.
Browse all the documentation β
| If you want to | Read |
|---|---|
| Install it with no prior experience | Start here |
| Set it up well in ten minutes | First steps |
| Learn what it can do | Using Scriptorium |
| Connect a device | Kobo, KOReader, Kindle, email and OPDS |
| Deploy it on a NAS, Pi or server | Installation reference |
| Reach it from anywhere, with HTTPS | Remote access |
| Keep it updated and safe | Updating and backups, Security |
| Run it for others | Administration, Automation, Configuration reference |
| Fix a problem | Troubleshooting |
| Contribute | Development, Releasing |
Bug reports, ideas, translations and pull requests are welcome. Start with CONTRIBUTING.md. Backend fixes that also apply to Calibre-Web-Automated are best proposed upstream too, so both projects benefit. To report a security issue, please follow SECURITY.md.
Scriptorium stands on the shoulders of three projects and their contributors:
- Calibre-Web-Automated by crocodilestick and contributors: the automation, Kobo and KOReader sync, duplicates, statistics and much more that Scriptorium builds on.
- Calibre-Web by janeczku and contributors: the web library at the core.
- Calibre by Kovid Goyal and contributors: conversion and metadata.
Scriptorium redesigns the whole interface and readers, adds personal styles, highlights, a year in books, history import, per-user devices and an installable app, and hardens security. The backend stays close to upstream so fixes can flow both ways.
Scriptorium is free software under the GNU General Public License v3.0 or later and comes with no warranty. Source files keep their original copyright notices. Third-party libraries and fonts are listed in NOTICE and CONTRIBUTORS.


