Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/johnfactotum/foliate-js/llms.txt

Use this file to discover all available pages before exploring further.

epub.js implements a full EPUB 2 and EPUB 3 parser. It reads the package document (OPF), parses the spine and manifest, resolves the navigation document or NCX for the table of contents, handles encrypted or obfuscated fonts, and returns a book object that satisfies the foliate-js book interface. The module has no hard dependencies — it only requires a zip loader object and, optionally, a SHA-1 implementation for font deobfuscation.

Instantiation

const { EPUB } = await import('./epub.js')
const loader = await makeZipLoader(file)  // from view.js
const book = await new EPUB(loader).init()
The EPUB constructor accepts a loader object directly. Call .init() to parse the package and return the fully-initialised book object (the method returns this).
loader.loadText
function
required
Async function. Given a path string, returns the file contents as a string.
loader.loadBlob
function
required
Async function. Given a path string, returns the file as a Blob.
loader.getSize
function
required
Function. Given a path string, returns the uncompressed file size in bytes. Used to populate the .size property on each section.
loader.sha1
function
Optional async function that accepts a string and returns a Uint8Array SHA-1 digest. Required only when the EPUB contains fonts obfuscated with the IDPF algorithm and the page is not served over HTTPS. When omitted, the implementation defaults to crypto.subtle.digest('SHA-1', …), which is available only in secure contexts.

Zip loader

Both epub.js and comic-book.js depend on a loader object rather than a specific zip library. In view.js this is constructed with zip.js, which supports random access on File objects and HTTP range requests without loading the entire archive into memory:
const makeZipLoader = async file => {
    const { configure, ZipReader, BlobReader, TextWriter, BlobWriter } =
        await import('./vendor/zip.js')
    configure({ useWebWorkers: false })
    const reader = new ZipReader(new BlobReader(file))
    const entries = await reader.getEntries()
    const map = new Map(entries.map(entry => [entry.filename, entry]))
    const load = f => (name, ...args) =>
        map.has(name) ? f(map.get(name), ...args) : null
    const loadText = load(entry => entry.getData(new TextWriter()))
    const loadBlob = load((entry, type) => entry.getData(new BlobWriter(type)))
    const getSize = name => map.get(name)?.uncompressedSize ?? 0
    return { entries, loadText, loadBlob, getSize }
}
You can implement the loader interface yourself to read from any source — for example, view.js also provides makeDirectoryLoader for reading unpacked EPUBs from a directory entry.

The book interface

new EPUB(loader).init() resolves to the EPUB instance, which implements the standard book interface used across all foliate-js parsers:
Property / methodDescription
.sectionsArray of section objects, one per spine item. Each has .load(), .unload(), .createDocument(), .size, .cfi, .linear, and .id.
.tocParsed table of contents (from the EPUB 3 nav document or NCX). Each item has .label, .href, and .subitems.
.pageListParsed page list, same structure as .toc.
.landmarksParsed landmarks nav, or the EPUB 2 <guide> if no landmarks nav exists.
.metadataBook metadata following the Readium webpub manifest schema.
.renditionRendition properties (e.g. layout: 'pre-paginated' for fixed-layout EPUBs).
.dirPage progression direction: "rtl" or "ltr".
.resolveHref(href)Resolves a href string to { index, anchor }.
.resolveCFI(cfi)Resolves a CFI string to { index, anchor }.
.splitTOCHref(href)Splits a TOC href into [path, fragment].
.getTOCFragment(doc, id)Returns the DOM node for a TOC fragment identifier.
.isExternal(uri)Returns true if the URI should be opened externally.
.getCover()Async. Returns the cover image as a Blob, or null.
.getMediaOverlay()Returns a MediaOverlay instance for EPUB Media Overlays (SMIL).
.destroy()Revokes all blob URLs created during loading.
.transformTargetAn EventTarget that fires "data" events, allowing callers to transform book resources as they load.

Media overlays

For EPUBs with EPUB 3 Media Overlays, call .getMediaOverlay() after .init(). The returned MediaOverlay object is an EventTarget with the following interface:
const overlay = book.getMediaOverlay()

// start playback at a given section index
await overlay.start(sectionIndex)

overlay.pause()
overlay.resume()
overlay.stop()
overlay.prev()
overlay.next()
overlay.setVolume(0.8)   // 0–1
overlay.setRate(1.25)    // playback rate
The overlay dispatches "highlight" and "unhighlight" custom events whose detail carries the SMIL text reference, which view.js uses to scroll the renderer and apply the active-class from the book’s media metadata.

Font deobfuscation

epub.js supports both IDPF and Adobe font obfuscation algorithms. The IDPF algorithm (http://www.idpf.org/2008/embedding) derives the XOR key from the book’s unique identifier using SHA-1. The Adobe algorithm (http://ns.adobe.com/pdf/enc#RC) uses the UUID embedded in the <dc:identifier> element.
The default SHA-1 implementation uses crypto.subtle, which is only available in secure contexts (HTTPS or localhost). Without HTTPS, pass your own SHA-1 function as sha1 on the loader object.

CFI support

EPUB CFIs (Canonical Fragment Identifiers) are parsed and resolved via epubcfi.js. The EPUB class stores a pre-computed base CFI for each spine item and exposes .resolveCFI(cfi) for navigating to a full CFI string. The view.js layer builds and round-trips CFIs for bookmarks and reading-position persistence.

Build docs developers (and LLMs) love