19 releases
Uses new Rust 2024
| 0.6.9 | Dec 2, 2025 |
|---|---|
| 0.6.8 | Nov 29, 2025 |
| 0.6.6 | Jul 14, 2025 |
| 0.5.0 | Apr 9, 2023 |
| 0.0.0 |
|
#255 in Parser implementations
25 downloads per month
390KB
5K
SLoC
rbook

A fast, format-agnostic, ergonomic ebook library with a focus on EPUB.
The primary goal of rbook is to provide an easy-to-use high-level API for handling ebooks.
Most importantly, this library is designed with future formats in mind
(CBZ, FB2, MOBI, etc.) via core traits defined within the ebook
and reader module, allowing all formats to share the same "base" API.
Documentation
Features
Here is a non-exhaustive list of the features rbook provides:
| Feature | Overview | Documentation |
|---|---|---|
| EPUB 2 and 3 | Read-only (for now) view of EPUB 2 and 3 formats. |
epub module |
| Reader | Random‐access or sequential iteration over readable content. | reader module |
| Detailed Types | Abstractions built on expressive traits and types. | |
| Metadata | Typed access to titles, creators, publishers, languages, tags, roles, attributes, and more. | metadata module |
| Manifest | Lookup and traverse contained resources such as readable content (XHTML) and images. | manifest module |
| Spine | Chronological reading order and preferred page direction. | spine module |
| Table of Contents (ToC) | Navigation points, including the EPUB 2 guide and EPUB 3 landmarks. | toc module |
| Resources | Retrieve bytes or UTF-8 strings for any manifest resource. | resource module |
Default crate features
These are toggleable features for rbook that are
enabled by default in a project's cargo.toml file:
| Feature | Description |
|---|---|
| prelude | Convenience prelude only including common traits. |
| threadsafe | Enables constraint and support for Send + Sync. |
Usage
rbook can be used by adding it as a dependency in a project's cargo.toml file:
[dependencies]
rbook = "0.6.9" # with default features
# rbook = { version = "0.6.9", default-features = false } # excluding default features
WebAssembly
The wasm32-unknown-unknown target is supported by default.
Examples
Opening and reading an EPUB file
use rbook::{Epub, prelude::*}; // Prelude for traits
fn main() {
// Open an epub from a file or directory
// * `Read + Seek` implementations supported via `read(...)`
let epub = Epub::options()
.strict(false) // Disable strict checks (`true` by default)
.open("tests/ebooks/example_epub")
.unwrap();
// Create a reader instance
// * Configurable via `reader_builder()`
let mut reader = epub.reader();
// Print the readable content
while let Some(Ok(data)) = reader.read_next() {
assert_eq!("application/xhtml+xml", data.manifest_entry().media_type());
println!("{}", data.content());
}
}
Accessing metadata: Retrieving the main title
use rbook::{Epub, prelude::*};
use rbook::ebook::metadata::{LanguageKind, TitleKind};
fn main() {
let epub = Epub::open("tests/ebooks/example_epub").unwrap();
// Retrieve the main title (all titles retrievable via `titles()`)
let title = epub.metadata().title().unwrap();
assert_eq!("Example EPUB", title.value());
assert_eq!(TitleKind::Main, title.kind());
// Retrieve the first alternate script of a title
let alternate_script = title.alternate_scripts().next().unwrap();
assert_eq!("サンプルEPUB", alternate_script.value());
assert_eq!("ja", alternate_script.language().scheme().code());
assert_eq!(LanguageKind::Bcp47, alternate_script.language().kind());
}
Accessing metadata: Retrieving the first creator
use rbook::{Epub, prelude::*};
use rbook::ebook::metadata::LanguageKind;
fn main() {
let epub = Epub::open("tests/ebooks/example_epub").unwrap();
// Retrieve the first creator
let creator = epub.metadata().creators().next().unwrap();
assert_eq!("John Doe", creator.value());
assert_eq!(Some("Doe, John"), creator.file_as());
assert_eq!(0, creator.order());
// Retrieve the main role of a creator (all roles retrievable via `roles()`)
let role = creator.main_role().unwrap();
assert_eq!("aut", role.code());
assert_eq!(Some("marc:relators"), role.source());
// Retrieve the first alternate script of a creator
let alternate_script = creator.alternate_scripts().next().unwrap();
assert_eq!("山田太郎", alternate_script.value());
assert_eq!("ja", alternate_script.language().scheme().code());
assert_eq!(LanguageKind::Bcp47, alternate_script.language().kind());
}
Extracting images from the manifest
use rbook::{Epub, prelude::*};
use std::{fs, path::Path};
fn main() {
let epub = Epub::open("tests/ebooks/example_epub").unwrap();
// Create an output directory for the extracted images
let out = Path::new("extracted_images");
fs::create_dir_all(&out).unwrap();
for image in epub.manifest().images() {
// Read the raw image bytes
let bytes = image.read_bytes().unwrap();
// Extract the filename from the href and write to disk
let filename = image.href().name().decode(); // Decode as EPUB hrefs may be URL-encoded
fs::write(out.join(&*filename), bytes).unwrap();
}
}
More examples are available in the documentation: https://docs.rs/rbook
Dependencies
~3.5MB
~63K SLoC