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.
- Same API, zero migration cost — change one import line and everything works
- Full TypeScript strict mode — generated
.d.tsfrom 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/nodeparses EPUBs server-side withlinkedom - Active maintenance — 20+ bug fixes and counting
Note: Built at 3ook.com and provided as-is. Forked from epubjs v0.3.93 by Fred Chasen / FuturePress.
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.
npm install @likecoin/epub-tsChange one line — everything else stays the same:
- import ePub from "epubjs";
+ import ePub from "@likecoin/epub-ts";import ePub from "@likecoin/epub-ts";
const book = ePub("/path/to/book.epub");
const rendition = book.renderTo("viewer", { width: 600, height: 400 });
rendition.display();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();
});Extract metadata, table of contents, and chapter HTML server-side. Requires linkedom:
npm install linkedomimport { 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));import {
Book, EpubCFI, Rendition, Contents, Layout,
Section, Spine, Locations, Navigation, PageList,
Resources, Packaging, Archive, Store,
Annotations, Themes, Mapping,
} from "@likecoin/epub-ts";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 |
| 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 |
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+.
See PROJECT_STATUS.md for current status and what to work on.
For AI agents contributing to this project, see AGENTS.md.
BSD-2-Clause (same as epubjs)
- epubjs by Fred Chasen / FuturePress — the original library this is forked from
- jszip — ZIP file handling
Built by 3ook.com
3ook is a Web3 eBook platform where authors publish EPUB ebooks and readers collect them as digital assets.
- epubjs — Original EPUB reader library
- epubcheck-ts — TypeScript EPUB validator (also by 3ook.com)