What's Changed
This release preserves books that go missing from your library, lets you edit KOReader custom metadata and covers from the web UI, aligns metadata discovery with KOReader across all sidecar locations, and adds reverse-proxy authentication with sub-path hosting.
Breaking Changes
- Non-
GET/HEAD/OPTIONSAPI requests must now sendX-KoShelf-Request: 1and are rejected when the browser reports aSec-Fetch-Siteother thansame-origin. The web UI sends the header automatically; scripts calling write endpoints must add it - Reading, annotation, and review writeback endpoints now require the
X-Metadata-Revisionheader taken from the item details. Missing headers return 400; stale revisions return 409. Older API clients must be updated - The library cache schema changed, so existing caches are rebuilt on first start
- In serve mode, derived media now lives under
<data-path>/assets, matching the/assetsURLs; the old top-level media folders are removed
Library Preservation
- Books whose ebook disappears (deleted, moved, or on an unplugged drive) now stay in the library as Archived, with status, annotations, statistics, and cover intact
- KoShelf saves a copy of each book's KOReader metadata and cover under
<data-path>/library/, independent of the SQLite cache. Returning books become available again automatically - Added archive badges and availability filters, also in static exports with a persistent
--data-path - Added
--enable-library-managementto remove archived books from the UI, with--archive-retention-days(number of days,0, orforever; default30) controlling how long their saved files are kept - Archive mode is enabled by default with persistent storage and can be disabled with
--archive-enabled false - Missing or inaccessible library roots no longer prevent startup when archives are enabled. Warnings explain the cause, and watch mode recovers automatically when access is restored
Custom Metadata and Covers
- With writeback enabled, the book details edit dialog can now override title, authors, series, series index, language, keywords, and description, and upload or reset a custom cover
- Edits are stored in KOReader's own
custom_metadata.luaandcover.*files, so they show up on your devices, and they also work for books that have never been opened in KOReader - KoShelf imports existing custom metadata and covers from adjacent,
docsettings, andhashdocsettings.sdrfolders, honoring the new--document-metadata-foldersetting (KOSHELF_DOCUMENT_METADATA_FOLDER) - Large cover uploads are downscaled to fit e-ink screens; smaller covers are kept byte-for-byte
- Edits are guarded by per-file revisions (
X-Edit-Revision); archived books stay read-only - A notice explains how to refresh KOReader's caches after an edit
KOReader Metadata
--docsettings-pathand--hashdocsettings-pathcan now be combined. Adjacent sidecars are always considered, and the newest valid metadata wins, following KOReader's ordering, so libraries migrating between locations keep working- Valid
.oldbackups are used when the primary sidecar is missing or invalid. An explicit edit restores the primary from the backup and never modifies the backup itself - Writeback now rechecks the source before writing and rejects edits against metadata that changed in the background; open editors keep their drafts
- Configured central metadata directories may be temporarily unavailable; KoShelf watches the nearest available ancestor and reconnects automatically
- The Lua writer refuses to rewrite files containing values it cannot preserve, instead of silently dropping them, and keeps float and boolean keys
Server
- Added
--auth-proxy-peersso explicitly listed reverse proxies (for example Home Assistant ingress or an SSO gateway) can authenticate users viaX-KoShelf-Userand serve KoShelf under a sub-path viaX-Forwarded-Prefix. Requires--enable-auth; proxy logins never receive session cookies - Added
--bind-address(default0.0.0.0) - The web UI now works when hosted below a path prefix
- See Reverse-Proxy Authentication for setup and security requirements
Internal
- Patched
rustlsadvisories and updated backend and frontend dependencies - Replaced ESLint with Oxlint and refreshed CI and release toolchain pins, including Zig 0.17 and cargo-zigbuild 0.23.4
Full Changelog: 2026.8.0...2026.10.0