PDF → EPUB
A browser-based PDF-to-EPUB 3 converter for StoryOrigin, built for illustrated books with local processing and fixed-layout pages.
Why I Built It
I designed book covers for independent authors before moving into engineering, so I know how much the look of a book matters. StoryOrigin hired me to build a PDF-to-EPUB converter for authors who already had illustrated PDFs and needed an ebook version.
I delivered a self-contained JavaScript module their team could add to its author tools. Conversion runs in the browser, without uploading the PDF or relying on a backend. The module returns an EPUB 3 file as a Blob.
Product Decisions
Keep the page design. The converter makes a fixed-layout EPUB, rendering each PDF page as a JPEG rather than trying to reflow an illustrated book.
Handle picture-book spreads. It reads page dimensions to spot narrow covers and wide interior pages. Each wide page stays intact; narrow covers are placed on a matching landscape canvas, with a separate portrait cover image for the library thumbnail. Authors can override the detection when the PDF gives too few clues.
Make integration simple. The public API exposes convertToEpub, detectSpreadFormat, and setWorker. StoryOrigin can bring its own interface and use the resulting Blob for download or upload.
Engineering Decisions
Work within the browser’s limits. pdf.js parses the file with a worker. Pages render one at a time, reusing the main canvas to limit memory use; zip.js handles ZIP compression with a worker.
Manage image size per page. The converter gives each page a share of a configurable size budget, set to 17 MB by default. Pages that exceed their share are tried at lower JPEG quality until they fit or reach a quality floor.
Package the EPUB correctly. It creates the XHTML pages, navigation, metadata, and images, then writes the required mimetype entry first and uncompressed in the EPUB ZIP.
How a PDF Becomes an EPUB
PDF file
read locally in the browser
Page scan
detect narrow covers and wide spreads
Page rendering
one page at a time; pad narrow covers when needed
JPEG encoding
adjust quality against the per-page budget
EPUB packaging
add fixed-layout pages, metadata, and navigation
EPUB Blob
return to the calling app
Hard Parts
Supporting spreads without changing ordinary books. Spread support came after the core converter was working. I kept detection and cover padding in a separate path so PDFs with uniform pages still follow the original flow.
Balancing size and image quality. The budget is a target, not a guaranteed cap. I chose a JPEG quality floor to protect the artwork, even though an unusually large book can still exceed the target.
What’s Next
- Mixed-size PDFs — improve handling when page dimensions vary outside the usual cover-and-spread pattern.
- Batch conversion — process several files in a queue.