Skip to content

likecoin/epub.ts

Repository files navigation

epub.ts (@likecoin/epub-ts)

CI npm License

Drop-in replacement for epubjs — same API, fully typed, 1 runtime dependency, actively maintained.

A complete TypeScript rewrite of epubjs v0.3.93 with strict mode, modern tooling, and ongoing bug fixes — without breaking your existing code.

What you get

  • Same API, zero migration cost — change one import line and everything works
  • Full TypeScript strict mode — generated .d.ts from source, so autocomplete matches runtime
  • 1 runtime dependency (jszip) — smaller bundle, simpler supply chain
  • 970+ tests across 40 files — Vitest with robust coverage
  • Vite build — ESM, CJS, and UMD outputs out of the box
  • Node.js support@likecoin/epub-ts/node parses EPUBs server-side with linkedom
  • Active maintenance20+ bug fixes and counting

Note: Built at 3ook.com and provided as-is. Forked from epubjs v0.3.93 by Fred Chasen / FuturePress.

Performance

Head-to-head numbers on two Project Gutenberg fixtures: a small book (Alice in Wonderland #11, 185 KB) and a large book (War and Peace #2600, 1.7 MB). Apple M4 Pro, macOS 26.4, headless Chrome 146, Node 20, median of 10–15 iterations. Run the bench yourself with npm run bench; see bench/README.md for full methodology and caveats.

Metric epubjs 0.3.93 @likecoin/epub-ts Δ
Bundle size (gzip, KB) 132.8 57.5 −56.7%
Alice (185 KB)
Cold parse (ms) 2.2 2.2 ≈ 0
First display (ms) 96.8 83.4 −13.8%
locations.generate(1000) (ms) 1760.3 10.4 −99.4%
currentLocation() (ms / call) 0.106 0.060 −43.8%
War and Peace (1.7 MB)
Cold parse (ms) 11.7 7.9 −33.1%
First display (ms) 90.1 91.9 ≈ 0
locations.generate(1000) (ms) 42903.3 158.9 −99.6%
currentLocation() (ms / call) 0.196 0.153 −22.1%

43 seconds → 159 ms on locations.generate() for a 1.7 MB book: this is the single biggest user-visible win, and it's what the 0.4.9 locations optimization was aimed at. Both libraries produce the same output count (169 locations for Alice, 429 for War and Peace) — the delta is real work, not a short-circuit.

currentLocation() — the pagination / CFI-range query called on every page turn — exercises the 0.6.0 canvas text measurement and 0.6.1 Mapping.findStart/findEnd binary search and is roughly 2× faster as a result. next-page timings are omitted from the table because both libraries converge on a frame-paced ~33 ms, which doesn't differentiate them.

Get started

Install

npm install @likecoin/epub-ts

Migrate from epubjs

Change one line — everything else stays the same:

- import ePub from "epubjs";
+ import ePub from "@likecoin/epub-ts";

Render an EPUB (browser)

import ePub from "@likecoin/epub-ts";

const book = ePub("/path/to/book.epub");
const rendition = book.renderTo("viewer", { width: 600, height: 400 });
rendition.display();

Load from file input

import ePub from "@likecoin/epub-ts";

const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener("change", async (event) => {
	const file = event.target.files[0];
	const data = await file.arrayBuffer();
	const book = ePub(data);
	const rendition = book.renderTo("viewer", { width: 600, height: 400 });
	rendition.display();
});

Parse on Node.js (no browser needed)

Extract metadata, table of contents, and chapter HTML server-side. Requires linkedom:

npm install linkedom
import { Book } from "@likecoin/epub-ts/node";
import { readFileSync } from "node:fs";

const data = readFileSync("book.epub");
const arrayBuffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
const book = new Book(arrayBuffer);
await book.opened;

console.log(book.packaging.metadata.title);
console.log(book.navigation.toc.map(item => item.label));

const section = book.spine.first();
const html = await section.render(book.archive.request.bind(book.archive));

Named exports

import {
	Book, EpubCFI, Rendition, Contents, Layout,
	Section, Spine, Locations, Navigation, PageList,
	Resources, Packaging, Archive, Store,
	Annotations, Themes, Mapping,
} from "@likecoin/epub-ts";

API reference

Full documentation: likecoin.github.io/epub.ts

Class What it does
Book Load, parse, and manipulate an EPUB
Rendition Render a book into a DOM element
Contents Manage content inside an iframe
EpubCFI Parse EPUB Canonical Fragment Identifiers
Locations Generate and query reading positions
Navigation Table of contents and landmarks
Annotations Highlights, underlines, and marks

Supported environments

Environment Import Notes
Modern browsers @likecoin/epub-ts Chrome 80+, Edge 80+, Firefox 74+, Safari 13.4+ (ES2020, Q1 2020)
Insecure contexts @likecoin/epub-ts http:// intranet and file:// deployments supported — runtime APIs gated behind secure contexts (crypto.randomUUID) are feature-detected with fallbacks
Vite / webpack @likecoin/epub-ts ESM or CJS
Node.js 18+ @likecoin/epub-ts/node Parsing only (no rendering); requires linkedom peer dep

Development

git clone https://github.com/likecoin/epub.ts.git
cd epub.ts
npm install
Script Description
npm run build Vite library build → dist/
npm test Run tests (Vitest)
npm run test:watch Run tests in watch mode
npm run typecheck tsc --noEmit
npm run lint ESLint
npm run lint:fix ESLint with auto-fix
npm run docs Generate API docs (HTML + Markdown)

Requires Node.js 18+ and npm 9+.

Contributing

See PROJECT_STATUS.md for current status and what to work on.

For AI agents contributing to this project, see AGENTS.md.

License

BSD-2-Clause (same as epubjs)

Acknowledgments

Built by 3ook.com

3ook is a Web3 eBook platform where authors publish EPUB ebooks and readers collect them as digital assets.

Related projects

  • epubjs — Original EPUB reader library
  • epubcheck-ts — TypeScript EPUB validator (also by 3ook.com)

About

A TypeScript fork of epubjs — parse and render EPUB documents in the browser.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors