š EBook-RS: Multi-Format Rust EBook Parser and Reader Engine (v0.11.6)
ebook-rs is a high-performance, 100% pure Rust parser and reader engine for EPUB 2, EPUB 3, MOBI, AZW3 (KF8), FB2 (FictionBook 2), KEPUB (Kobo EPUB), LIT (Microsoft Reader), CBZ (Comic Book ZIP), PDF, ODT, TXT, and MD formats, designed for full feature parity with epub.js and foliate-js.
ā” Feature Parity Matrix
š Format Support
| Feature |
š ebook-rs (v0.11.5) |
š¦ epub.js |
š foliate-js |
š¦ rbook |
| EPUB 2 & 3 Support |
ā
Full OPF + NCX/NAV |
ā
Yes |
ā
Yes |
ā
Yes |
| EPUB 3 Fixed-Layout (FXL) |
ā
2-page spread renderer |
ā
Yes |
ā
Yes |
ā No |
| MOBI & AZW3 (KF8) Support |
ā
Native PalmDOC LZ77 |
ā No |
ā
Yes |
ā No |
| FB2 (FictionBook 2) Support |
ā
Native XML + xlink:href |
ā No |
ā
Yes |
ā No |
| KEPUB (Kobo EPUB) Support |
ā
Native |
ā No |
ā
Yes |
ā No |
| LIT (Microsoft Reader) Support |
ā
Native |
ā No |
ā
Yes |
ā No |
| CBZ (Comic Book ZIP) Support |
ā
Native ZIP Images |
ā No |
ā
Yes |
ā No |
| PDF Support |
ā
pdf_oxide parser |
ā No |
ā No |
ā No |
| ODT (OpenDocument Text) |
ā
office_oxide |
ā No |
ā No |
ā No |
| TXT / Markdown Support |
ā
Auto-reflow sections |
ā No |
ā No |
ā No |
| Auto Format Detection |
ā
Magic-byte detection |
ā No |
ā No |
ā No |
š§ Navigation & Rendering
| Feature |
š ebook-rs (v0.11.5) |
š¦ epub.js |
š foliate-js |
š¦ rbook |
| IDPF CFI Engine |
ā
Parse / format / compare / range |
ā
Yes |
ā
Yes |
ā
Yes |
| CFI DOM Resolver |
ā
cfi.resolve_dom_path(html) |
ā
Yes |
ā
Yes |
ā No |
| Readium CFI Unified Locator |
ā
Full model |
ā
Yes |
ā
Yes |
ā No |
| Location / Reading Progress |
ā
locations_from_sections() |
ā
Yes |
ā
Yes |
ā
Yes |
| SMIL Media Overlays (Sync) |
ā
NPT clock parser |
ā
Yes |
ā
Yes |
ā No |
| EPUB NCX / NAV TOC Parsing |
ā
Deep recursive nav tree |
ā
Yes |
ā
Yes |
ā
Yes |
| RTL Text Auto-Injection |
ā
dir="rtl" + text-align:right |
ā
Yes |
ā
Yes |
ā No |
| Viewport Meta Parsing |
ā
Zero-alloc slice parse |
ā
Yes |
ā
Yes |
ā No |
| Reflow Paginator |
ā
ReflowPaginator::paginate_section |
ā
Yes |
ā
Yes |
ā No |
| Custom Font Injection |
ā
@font-face CSS injection |
ā
Yes |
ā
Yes |
ā No |
š Search & Analytics
| Feature |
š ebook-rs (v0.11.5) |
š¦ epub.js |
š foliate-js |
š¦ rbook |
| Full-Text Search |
ā
SIMD-accelerated |
ā No |
ā
Basic |
ā No |
| Regex Search |
ā
regex_search |
ā No |
ā No |
ā No |
| Search Context Snippets |
ā
<mark> highlights + offsets |
ā No |
ā
Yes |
ā No |
| Readium Search JSON Export |
ā
Readium-compliant JSON |
ā No |
ā
Yes |
ā No |
| NLP Reading Analytics |
ā
Word count / reading time / complexity |
ā No |
ā No |
ā No |
| Auto Language Detection |
ā
detect_language (whatlang) |
ā No |
ā No |
ā No |
š Annotations & Standards
| Feature |
š ebook-rs (v0.11.5) |
š¦ epub.js |
š foliate-js |
š¦ rbook |
| W3C Web Annotation (JSON-LD) |
ā
Full CRUD + to_w3c_json |
ā No |
ā
Yes |
ā No |
| Readium WebPub Manifest Export |
ā
book.to_webpub_manifest() |
ā No |
ā
Yes |
ā No |
| OPDS 1.2 Atom XML Catalog |
ā
OpdsFeed::parse_atom_xml |
ā No |
ā No |
ā No |
| OPDS 2.0 JSON Catalog |
ā
OpdsFeed::parse_json |
ā No |
ā No |
ā No |
| Readium LCP DRM Detection |
ā
License parse + expiry |
ā No |
ā
Yes |
ā No |
| MLA / Chicago Citations |
ā
book.to_mla_citation() |
ā No |
ā No |
ā No |
āļø Performance & Architecture
| Feature |
š ebook-rs (v0.11.6) |
š¦ epub.js |
š foliate-js |
š¦ rbook |
| Zero-Copy Memory-Mapped I/O |
ā
Book::from_mmap |
ā No |
ā No |
ā No |
| Lazy On-Demand Section Loading |
ā
load_section_lazy(i) |
ā No |
ā
Yes |
ā No |
| Async tokio API |
ā
book::async_api feature |
ā No |
ā No |
ā No |
| Zstd Compressed State Cache |
ā
export_zstd_cache |
ā No |
ā No |
ā No |
| O(1) Archive Asset Lookup |
ā
Dual-HashMap ZIP index |
ā No |
ā No |
ā No |
| SIMD UTF-8 Validation |
ā
simdutf8 (AVX2/NEON) |
ā No |
ā No |
ā No |
| SIMD Substring Search |
ā
memchr SIMD scanning |
ā No |
ā No |
ā No |
| AHash Fast Hash Maps |
ā
3ā5Ć faster lookups |
ā No |
ā No |
ā No |
| Single-Pass CSS Inliner |
ā
O(N) streaming builder |
ā No |
ā No |
ā No |
| CSS Versioned Href Fix |
ā
style.css?v=2 inlined |
ā No |
ā No |
ā No |
| Async Non-Blocking Web Font |
ā
media="print" onload |
ā
Yes |
ā
Yes |
ā No |
| Built-in Localhost Reader |
ā
tiny_http web server |
ā
Yes |
ā
Yes |
ā No |
š”ļø Security & Robustness
| Feature |
š ebook-rs (v0.11.6) |
š¦ epub.js |
š foliate-js |
š¦ rbook |
| Script Sanitizer (XSS Guard) |
ā
3-phase + entity decode |
ā
Partial |
ā
Partial |
ā No |
| Fuzzy Malformed XML Recovery |
ā
Entity repair + tag heal |
ā No |
ā No |
ā No |
| Legacy Charset Decoding |
ā
decode_bytes_with_encoding (encoding_rs) |
ā No |
ā No |
ā No |
| LCP AES-256-CBC Decryption |
ā
Real crypto via aes+cbc |
ā No |
ā
Partial |
ā No |
| DRM-Protected Book Detection |
ā
ADEPT + LCP detection |
ā No |
ā
Yes |
ā No |
| HTTP Security Headers |
ā
CSP / nosniff / SAMEORIGIN |
ā No |
ā No |
ā No |
| CBR RAR Format Error Guard |
ā
RAR v4 + v5 magic detection |
ā No |
ā No |
ā No |
| libFuzzer Fuzz Harnesses |
ā
fuzz_from_bytes + fuzz_cfi_parse |
ā No |
ā No |
ā No |
š§© Advanced & Developer Features
| Feature |
š ebook-rs (v0.11.6) |
š¦ epub.js |
š foliate-js |
š¦ rbook |
| Universal EPUB 3 Exporter |
ā
Any format ā EPUB3 bytes |
ā No |
ā No |
ā No |
| Book Fingerprint / Identity |
ā
SHA-based fingerprint |
ā No |
ā No |
ā No |
| SpeechSynthesis TTS Tokens |
ā
get_tts_tokens with char offsets |
ā No |
ā
Yes |
ā No |
| TTS Annotated HTML |
ā
<span class="tts-word"> injection |
ā No |
ā
Yes |
ā No |
| TreeSitter Code Highlighter |
ā
AST extraction |
ā No |
ā No |
ā No |
| Lightweight DOM AST Engine |
ā
EbookDomTree / DomNode |
ā No |
ā No |
ā No |
| EPUB Structural Validator |
ā
OPF + Spine + Manifest checks |
ā No |
ā No |
ā No |
Optional serde Feature |
ā
Compile without serde overhead |
ā N/A |
ā N/A |
ā No |
| WASM-Ready (no_std compat) |
ā
WASM build support |
ā
Yes |
ā
Yes |
ā No |
š What's New in v0.11.6
- Lazy On-Demand Section Loading ā
book.load_section_lazy(i) parses one section directly from the archive without caching all sections in RAM ā essential for large books.
- Real AES-256-CBC LCP Decryption ā
LcpDecryptor now uses proper aes + cbc + cipher crates (key = SHA-256(passphrase), IV = first 16 bytes of ciphertext) per the Readium LCP spec.
- Async API ā New
book::async_api module with from_file_async, from_bytes_async, and load_section_lazy_async via tokio (enable with features = ["async"]).
serde Feature Flag ā serde / serde_json are now optional (default on). Opt out with default-features = false to slash compile time for pure parsing use-cases.
- CSS Versioned Href Fix ā
style.css?v=2, style.css?cache=abc now correctly resolve and inline in the archive.
- cargo-fuzz Harnesses ā
fuzz_from_bytes and fuzz_cfi_parse libFuzzer harnesses in fuzz/. Run with cargo +nightly fuzz run fuzz_from_bytes.
- Dynamic LCP Expiry ā
LcpDecryptor now evaluates license expiration against the real system clock instead of a hardcoded date.
š What's New in v0.11.5
- Full Blackbox Test Suite (38 tests, 4.4 s) ā Complete coverage across all features: OPDS, charset decoding, EPUB3 exporter roundtrip, reflow paginator, mmap, fuzzy XML, and TTS word synchronization.
- O(1) Archive Lookups ā
Archive::contains now uses dual-HashMap constant-time lookups instead of O(N) linear scan.
- Zero-Alloc Viewport Parsing ā
parse_viewport_meta rewritten with zero-copy byte slices.
- Single-Pass CSS Inliner ā O(N²)
.replace() loops replaced with streaming O(N) builder.
- Zstd Cache Deduplication ā
export_zstd_cache deduplicates identical processed_html / raw_html entries, reducing cache size by up to 50%.
- Non-Blocking Font Loading ā Localhost reader now uses async
media="print" onload font loading with instant system font fallbacks, eliminating render-blocking delays.
š Quick Start Example
use ebook_rs::{Book, ReflowPaginator, Cfi};
fn main() -> Result<(), String> {
let mut book = Book::from_file("book.epub")?;
println!("Title: {}", book.metadata().title);
println!("Language: {:?}", book.detect_language());
println!("Sections: {}", book.spine().len());
let epub3_bytes = book.export_epub3_bytes()?;
let cache = book.export_zstd_cache()?;
let restored = Book::from_zstd_cache(&cache)?;
let search_results = book.search("quantum");
for res in search_results {
println!("Snippet: {}", res.snippet);
}
let tts_tokens = book.get_tts_tokens(0);
for token in tts_tokens {
println!("[{}..{}] {}", token.char_start, token.char_end, token.word);
}
Ok(())
}
š Documentation & Wiki
Detailed API documentation and integration guides are available in docs/API.md and WIKI.md.
š License
Licensed under the MIT License. Copyright (c) 2026 SV-Stark.