How to Create an EPUB from Scratch
Learn the internal structure of EPUB files and build one yourself — OPF manifests, XHTML chapters, CSS styling, and validation.
Most people treat EPUB as a black box. You throw a manuscript at some tool and hope for the best. But if you actually understand what's inside an EPUB, you gain total control over formatting, layout, and compatibility. So let's crack one open.
What Is an EPUB, Really?
An EPUB file is a ZIP archive with a .epub extension. That's it. Rename any .epub to .zip, extract it, and you'll find a structured set of files inside. The EPUB 3 spec (maintained by the W3C) defines exactly what goes where.
Here's the typical structure:
my-book.epub/
mimetype
META-INF/
container.xml
OEBPS/
content.opf
toc.xhtml
chapter-01.xhtml
chapter-02.xhtml
styles/
main.css
images/
cover.jpg
The mimetype File
This one's dead simple. It must be the first file in the ZIP, stored uncompressed, and contain exactly:
application/epub+zip
No newline at the end. No extra whitespace. Readers check this first to confirm they're dealing with an EPUB.
container.xml
Inside META-INF/, this file tells readers where to find the main package document:
<?xml version="1.0" encoding="UTF-8"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
<rootfiles>
<rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/>
</rootfiles>
</container>
The OPF Package Document
content.opf is the heart of your EPUB. It has three sections: metadata, manifest, and spine.
Metadata includes your book title, author, language, and a unique identifier. Manifest lists every single file in the publication — chapters, images, stylesheets, the nav document. Spine defines the reading order.
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" unique-identifier="uid">
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:title>My Book Title</dc:title>
<dc:creator>Your Name</dc:creator>
<dc:language>en</dc:language>
<dc:identifier id="uid">urn:uuid:12345-abcde</dc:identifier>
</metadata>
<manifest>
<item id="ch01" href="chapter-01.xhtml" media-type="application/xhtml+xml"/>
<item id="ch02" href="chapter-02.xhtml" media-type="application/xhtml+xml"/>
<item id="css" href="styles/main.css" media-type="text/css"/>
<item id="nav" href="toc.xhtml" media-type="application/xhtml+xml" properties="nav"/>
</manifest>
<spine>
<itemref idref="ch01"/>
<itemref idref="ch02"/>
</spine>
</package>
Writing XHTML Chapters
Each chapter is an XHTML file. Not HTML5 — XHTML, meaning it must be well-formed XML. Self-closing tags, quoted attributes, lowercase elements. Keep your markup clean and semantic.
Use EPUB supports a solid subset of CSS. You can control fonts, margins, line height, and colors. Where things get tricky: each reader app applies its own user-agent stylesheet, and users can override your choices (font size, typeface, background color). Design defensively. Use relative units ( Before distributing your EPUB, run it through EPUBCheck. It catches malformed XML, missing manifest entries, invalid metadata, and accessibility issues. Most ebook stores (including Apple Books and Kobo) reject files that fail validation. Building an EPUB by hand is educational, but for day-to-day work you probably want a converter. If you have a Word document, PDF, or plain text file, you can convert it directly., through , , and . Avoid Styling with CSS
em, %) instead of px. Don't assume a specific screen width. Test on multiple readers.Validation with EPUBCheck
The Faster Route
Related Tools