I Built a Pi Extension to Translate EPUBs Without Losing Their Structure
Purpose
I wanted to translate an EPUB without turning it into a pile of copied text and hoping the rebuilt book would still work.
An EPUB is more than chapter content. It is a package containing XHTML, a manifest, reading order, navigation, metadata, stylesheets, images, and sometimes footnotes. A workflow that only sends paragraphs to a model can lose tags and links, or produce an invalid EPUB.
So I built pi-epub-translator: a Pi extension that translates EPUB content by fragment, with review, progress tracking, and retry support.
How it works
The extension does not blindly translate every XHTML file.
The translation pipeline: inspect, review, translate, retry when needed, then verify the rebuilt EPUB.
First, it reads the EPUB manifest and spine. AI then proposes:
- which documents should be translated;
- which documents should stay unchanged;
- a glossary for proper names, places, institutions, and recurring terms.
The user can edit both the document scope and glossary before the run starts. The target language is also mapped to a BCP-47 code; Vietnamese, for example, becomes vi.
Fragments are stored in SQLite with their state, attempt count, lease, and result. Separate Pi workers run with --no-session, claim fragments through leases, and send heartbeats while they work. A fencing token prevents an old worker from overwriting a result after its lease has expired.
When every fragment is complete, the extension merges the translations into a copy of the source EPUB. Before producing the output, it checks the XML structure, tags, attributes, namespaces, links, page-break markers, and EPUB package members. If epubcheck is installed, it runs that as an additional check.
How to install and run it
Install the package:
pi install npm:pi-epub-translatorPut a DRM-free EPUB in input/, then start Pi normally:
piRun the command:
/translate-epubThe wizard asks for the source EPUB, model, thinking level, target language, and worker count. It then lets you review the proposed document scope and glossary before you confirm the run.
The translated book is written to output/. The source EPUB is not modified in place, and run state is kept in .parallel-translate/.
While a run is in progress, you can use:
/epub-progress
/epub-cancel
/epub-retry/epub-retry resets failed fragments and starts new workers instead of requiring the whole book to be translated again.
A real run
The GIF below shows a real run using:
gpt-5.6-luna;mediumthinking;- Vietnamese as the target language;
- 5 workers;
- all
46/46fragments completed.

A real run: configure, review, monitor progress, and produce the translated EPUB.
Limits
Structural validation does not guarantee literary quality. A model can preserve the markup and still miss tone, historical nuance, or context. A glossary improves consistency, but it does not replace editorial review.
The extension focuses on preserving EPUB structure, coordinating translation jobs, and making long runs observable and recoverable.
The source code is available at pi-epub-translator.