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