FolioFin
Native Linux Jellyfin Book Reader
Overview
FolioFin is a native Linux desktop reading client for Jellyfin media servers. If you self-host books on Jellyfin, FolioFin gives you a dedicated reader app — library browsing, EPUB/PDF/CBR reading, and reading progress that syncs back to your server.
Built with Tauri v2 and React, it runs as a native WebKitGTK window with no Electron overhead.
Why
Jellyfin has great apps for video and music, but its book support on Linux is an afterthought. The web UI is functional but not built for reading. FolioFin fills that gap: a focused, native reading experience that treats your book library as a first-class collection.
Features
Library
- Connects to any Jellyfin server with username/password auth
- Grid and list views with cover art, search, and sort
- Collapsible sidebar navigation
Reader
- EPUB — epub.js with paginated flow, dark / light / sepia themes, adjustable font size, font family, and margins
- PDF — PDF.js with dark invert mode for comfortable night reading
- CBR/CBZ — comic archive support via libarchive.js (WASM) and JSZip
- Table of contents panel and reader settings panel
Sync
- Reading progress synced to Jellyfin's playback API so position is preserved across sessions
- Local fallback in localStorage for offline use
Architecture
Tauri v2 (Rust)
└── WebKitGTK webview
└── React 19 + TypeScript + Vite
├── Tailwind CSS v4 (via @tailwindcss/vite)
├── Zustand v5 — persisted global state
├── Framer Motion — screen transitions & animations
├── epub.js — EPUB rendering
├── pdfjs-dist v5 — PDF rendering
└── libarchive.js — CBR comic extraction
All Jellyfin API calls are centralised in src/services/jellyfin.ts. The Zustand store (src/store/index.ts) manages auth state, library cache, and reader settings, persisted in localStorage.
Design
Deep dark theme built around CSS custom properties:
- Base:
#08080fnear-black background - Primary:
#7c3aedviolet-purple for interactive elements - Accent:
#06b6d4cyan for highlights and progress - Glass-morphism cards with backdrop-filter blur
- Framer Motion page transitions between library → detail → reader screens
Navigation Flow
Library screen
→ (click book tile) → Detail screen
→ (click Open Reader) → Reader screen
→ (back) → Detail → (back) → Library
Jellyfin Quirks Solved
Jellyfin's book API has some non-obvious edge cases:
HasPrimaryImageis null on some servers — cover detection usesImageTags?.PrimaryinsteadMediaSourcesis always empty for books — format detection falls back to thePathfile extension- CBR comic files (Spider-Man Reign) required libarchive.js WASM since JSZip doesn't handle RAR archives
comments