Releases: paviro/KoShelf
2026.4.3
What's Changed
This release brings faithful rendering for all KOReader highlight styles, polishes the annotation editing toolbar, and fixes a few resilience issues around metadata parsing and file watching.
Highlight Styles
- Invert and strikeout highlights are now rendered with their actual KOReader styling instead of falling back to a plain highlight
- Unrecognized highlight colors (from custom-patched KOReader installs) show a rainbow gradient instead of silently defaulting to yellow
- Style icon badge in annotation card headers to tell highlight, underline, strikeout, and invert apart at a glance
- Color picker is disabled for invert highlights, matching KOReader behavior
Bug Fixes
- Invalid UTF-8 in metadata — truncated multi-byte sequences in KOReader highlight text no longer blow up the parser
- Stats ID fallback — reading statistics fall back to the canonical item ID when the MD5 hash is missing showing stats on the item detail page even without a sidecar file when available
- File watcher self-healing — the watcher recovers when a DB writeback fails instead of stalling
Internal
- Reading metrics and summaries are pre-computed at export time as JSON per week/month/year, so the frontend fetches them directly instead of reassembling from raw day-level data
build.rssplit intobuild/{main,shared,react,compress,licenses,locale}.rsapp/run.rssplit intobootstrap.rsand per-command modules (serve,export,set_password,licenses)- Removed render-time state sync patterns in favor of event-driven updates and keyed remounts
- Added optimistic-cache test coverage
Full Changelog: 2026.4.2...2026.4.3
2026.4.2
What's Changed
This patch release improves small-screen layouts, unifies overlay and button behavior, and polishes text sizing across the UI.
UI & Layout Fixes
- Improved annotation card layout on small screens — section headers now space badges and controls properly, and page numbers display more compactly on narrow viewports
- Larger hover preview text — book description text and series pills in hover previews are slightly larger for better readability
- Responsive button labels — icon buttons like "Settings" and "Navigation" in the reader now show their text labels on wider screens, improving discoverability on desktop
Overlay Improvements
- Unified overlay positioning — all popover-style elements (color pickers, highlight pickers, settings panels, dropdowns) now use a single positioning system that respects the app header and mobile navigation, and auto-hides when the anchor scrolls off-screen
Localization
- Added trailing period to the "Statistics from KOReader" subtitle across all languages
- Added localized labels for reader settings and navigation drawer buttons in all 8 supported languages
Full Changelog: 2026.4.1...2026.4.2
2026.4.1
What's Changed
This patch release reduces binary size with gzip-compressed embedded assets, improves the reader highlight navigation experience, fixes several UI issues in the recap section, and corrects session detection on iOS devices.
Binary Size & Asset Compression
- Gzip-compressed embedded assets: frontend files and fonts are now gzip-compressed at build time and served with
Content-Encoding: gzipto clients that support it, significantly reducing the compiled binary size - Decompression fallback for clients that don't advertise gzip support — the server transparently decompresses on the fly
- Share image fonts sourced from npm instead of downloaded at build time
Third-Party Licenses
- Embedded license notices: third-party dependency licenses (Rust + JS) are now collected at build time and bundled into the binary, replacing the static
THIRD_PARTY_LICENSES.mdfile
Reader
- Pulse animation when navigating to a highlight from the navigation drawer — the target highlight briefly pulses so you can spot it on the page - same as when opening a highlight from the library item detail page
Fixes
- iOS user agent detection: Safari, Chrome (CriOS), Firefox (FxiOS), and Edge (EdgiOS) on iOS are now correctly identified in the session management UI
- Share images regenerated when no data has changed but the cached files are missing from disk
- Recap active days circle graph visibility now uses container queries for reliable show/hide behavior
- Recap stat labels allow word breaking and document
langattribute is set so the browser can hyphenate correctly - MetricCard small-size variant uses consistent layout breakpoints and label sizing
API Changes
- The
/api/siteresponse now groupsauthenticatedandpassword_policyunder anauthobject (previously flat top-level fields); the redundantauth_enabledcapability flag has been removed
Updated Dependencies
- Added flate2 (gzip compression/decompression), @expo-google-fonts/gelasio, license-checker-rseidelsohn
- Removed ureq build dependency (font download) and
THIRD_PARTY_LICENSES.md
Full Changelog: 2026.4.0...2026.4.1
2026.4.0
What's Changed
This release adds an in-app reader, the ability to edit annotations and sync changes back to KOReader, a per-page reading activity heatmap, and optional password authentication.
In-App Reader
- Full EPUB, FB2, MOBI, and CBZ reader built into the web UI — open books directly from the library detail page (#65)
- Navigation drawer with table of contents, highlights, and bookmarks — tap any entry to jump to that position
- Presentation settings: font size, line spacing, word spacing, margins, hyphenation, and embedded font toggling. Settings persist per book (#68)
- Existing KOReader annotations (highlights, bookmarks) are rendered inline with colored overlays, notes can be opened by clicking a highlight
- Keyboard navigation (arrow keys, page up/down) and a scrubber bar for quick seeking
Writeback Mutations
- Edit annotations — change highlight colors, drawing styles, and notes directly in the web UI, then sync changes back to KOReader's
.sdr/metadata.*.luasidecar files (#69) - Delete annotations from the web UI with the same sidecar sync
- Edit item metadata — set ratings (1–5 stars), reading status (reading/complete/abandoned), and review notes
- Requires
--enable-writeback(disabled by default)
Page-Level Activity Heatmap
- Per-page reading time visualization with color-coded bars and chapter boundary overlays (#70)
- Annotation markers (highlights, bookmarks, notes) shown on corresponding page bars
- Filter by individual completion to compare reading sessions
Authentication
- Optional password authentication for serve mode (#62)
- Argon2 password hashing, PASETO v4 session tokens (30-day expiry), and per-IP rate limiting (5 attempts/min)
- Session management UI — view active sessions, revoke others on password change
- Trusted proxy support (
--trusted-proxies) for correct client IP behind reverse proxies - Set or rotate passwords via
koshelf set-password(supports--randomfor auto-generated credentials)
Other Changes
- File downloads: original EPUB/FB2/MOBI/CBZ files can now be served from the library detail page (#64)
- Subcommand CLI: the CLI is now
koshelf serve/koshelf export/koshelf set-passwordinstead of a flat flag structure. All options support environment variables (KOSHELF_LIBRARY_PATH,KOSHELF_DATA_PATH, etc.) - Smarter file watcher: settle-based debounce (waits for 2 seconds of quiet) replaces the fixed 1-second sleep — a Syncthing sync now triggers one rebuild instead of ~11
- Cleaner logs: startup info and watched directories each collapse into a single line
- Hidden flow pages: KOReader's "hidden flow" pages (front matter, etc.) are now supported so page counts and activity data match what you see on the device
Updated Dependencies
- TypeScript 5.7 → 5.9, jsdom 28 → 29, @tanstack/react-query 5.66 → 5.95
- zip 8.1 → 8.4, ureq 3.1 → 3.3
- Added foliate-js (reader engine), Noto Sans/Serif and Quicksand fonts
- Added argon2, rusty_paseto, governor, uuid, dashmap (auth stack)
- Removed server-side Fluent/ICU localization crates (localization is frontend-only now)
Warning
Breaking CLI changes: The flat koshelf --library-path ... --output ... invocation is replaced by subcommands. Use koshelf serve --library-path ... --data-path ... or koshelf export <output> --library-path .... Run koshelf --help for the
full reference.
Full Changelog: v2026.3.0...2026.4.0
2026.4.0b3
What's Changed
Note
This is a pre-release beta!
This beta adds page activity (similar to bookmap in KOReader)
2026.4.0b2
What's Changed
Note
This is a pre-release beta!
This beta adds annotation writeback and full reader customization
- Annotation writeback: Highlights, bookmarks, and reviews can now be edited and deleted directly in the KoShelf UI. Changes are synced back to the KOReader sidecar files on disk. (#69)
- Reader presentation settings: The in-app reader gains comprehensive style controls — font family, font size, line spacing, word spacing, and margins — organized into collapsible settings sections with per-value editing and a reset option.
(#68) - Book navigation drawer: A new slide-out drawer in the reader provides quick access to the table of contents and annotation lists, making it easy to jump between sections and highlights.
- Hidden-flow page tracking: KOReader's non-linear flow points (e.g. footnote pages) are now parsed and subtracted from page totals, so reading statistics and completion detection reflect the actual linear page count.
- Dependency upgrades: Major and minor dependency updates across the stack; unused Rust crates removed.
API changes
PATCH /api/items/:id/annotations/:id— edit an annotation (highlight text, color, bookmark, review fields)DELETE /api/items/:id/annotations/:id— delete an annotation
Full Changelog: 2026.4.0b1...2026.4.0b2
2026.4.0b1
What's Changed
Note
This is a pre-release beta!
This release adds authentication, an in-app reader, file downloads, and restructures the CLI around explicit subcommands.
- Optional password authentication: Serve mode gains
--enable-authwith cookie-based sessions. Includes a frontend login page, password change UI, and session management in settings. - In-app reader with annotation deep linking: Book detail pages now link into a full in-app reader powered by foliate-js. Highlights and bookmarks open directly at the corresponding position.
- Item file downloads: Original book/comic files can now be downloaded from the library UI when available.
- Explicit CLI subcommands: The implicit serve-vs-export mode detection has been replaced with
serve,export,set-password,list-languages, andgithubsubcommands. All flags now support environment variable overrides (KOSHELF_*).
New API endpoints
POST /api/auth/login— authenticate and receive a session cookiePOST /api/auth/logout— end the current sessionPUT /api/auth/password— change the authentication passwordGET /api/auth/sessions— list active sessionsDELETE /api/auth/sessions/:id— revoke a specific session
Warning
Breaking CLI changes: KoShelf now uses subcommands (koshelf serve, koshelf export, koshelf set-password). The previous flag-based mode detection (-o for export, otherwise serve) no longer works. Update scripts and container entrypoints accordingly.
Full Changelog: v2026.3.0...2026.4.0b1
2026.3.0
What's Changed
Major internal rewrite. Most changes are under the hood but have an impact on resource usage (#59).
- Much lower RAM usage: Previously all API responses were pre-computed and held in memory, and cover images were all buffered during the library build. Now library data lives in SQLite, statistics are computed per request, and covers are written to disk one at a time during ingest.
- Support for persistent data dir: Extracted cover images and data can now be stored in a persisted directory making startup much faster.
- Incremental updates: File changes are now detected by fingerprint and only affected items are re-processed, instead of rebuilding the entire library.
- Config file support: Settings can now be provided via
koshelf.toml(seekoshelf.example.toml). CLI flags still override. - New reading API: All reading data moves to
/api/reading/*with query parameters for scope, date range, and timezone. - Added jemalloc allocator on non-Windows platforms
Security
- Fixed potential path traversal in CBR extraction and EPUB path resolution
- Lua metadata parser — disabled all standard libraries and bytecode loading to prevent code execution via malicious sidecar files
- Removed permissive CORS policy (embedded frontend is same-origin)
- Added
X-Content-Type-Options,X-Frame-Options, andReferrer-Policysecurity headers
Updated dependencies
- Tailwind CSS v3 → v4
- react-router v6 → v7, Vite v6 → v8, @vitejs/plugin-react v4 → v6
- rusqlite → sqlx
- Bumped event-calendar, typescript-eslint, vitest, @types/node, and other minor frontend deps
Note
Starting with this release, KoShelf uses calendar versioning (YYYY.M.patch) instead of semantic versioning. This version is 2026.3.0.
Warning
Breaking API changes: /api/activity/* and /api/completions/* have been removed in favor of /api/reading/*. Site capabilities has_activity/has_completions are now a single has_reading_data flag. The response envelope is now { data, meta: { version, generated_at } } across all endpoints. See docs/API.md for the new reference.
Full Changelog: v2.4.1...v2026.3.0
2.4.1
What's Changed
- Fixed library detail page not correctly using stable page metadata
Note
Stable page numbering support requires metadata only written by KOReader releases after Ghost (currently nightly only). After updating KOReader you can use KoReader-PopulateStablePageKOReader to update the metadata for books you have already finished.
Full Changelog: v2.4.0...v2.4.1
2.4.0
What's Changed
- Added support for stable page numbers (fixes #54)
- Adjusted default values for
heatmap-scale-maxandmin-time-per-day - Fixed total read time on recap and yearly stats differing
- Weekly stats averages now don't use the full week for the average on current week
- Improved unit formatting in metrics cards
Note
Stable page numbering support requires metadata only written by KOReader releases after Ghost (currently nightly only). After updating KOReader you can use KoReader-PopulateStablePageKOReader to update the metadata for books you have already finished.
Full Changelog: v2.3.0...v2.4.0