We built one to see for ourselves. Three chapters of Markdown, run through Pandoc into an EPUB, unzip into thirteen files: a mimetype flag, two navigation documents, one XHTML page per chapter, and a cover image. None of them record a page count. Laid out at FileFlip's own page size, that same archive runs 16 pages at 11-point type and 44 pages at 18-point, without a byte of it changing.
What's actually inside an EPUB file?
A ZIP archive, nothing more exotic than that. Change the extension to .zip and any archive tool opens it like any other one. If you already have one and just want the words in a fixed-page file, convert EPUB to PDF and skip ahead; the rest of this page covers what that trades away.
Inside, a reading app finds mimetype, a twenty-byte text file naming the format, stored as the archive's first entry and left uncompressed so a file sniffer can identify an EPUB by reading only the first few bytes. META-INF/container.xml points to the real table of contents, EPUB/content.opf, which lists every file in the book and the order they're meant to be read in. That's the shape the EPUB 3.3 specification describes: a ZIP-based container carrying a package document, a spine, and a set of content documents. The actual text lives in one XHTML file per chapter, styled by a shared CSS file, with images sitting in their own folder.
| File | What it holds |
|---|---|
mimetype |
application/epub+zip, stored uncompressed, first entry in the archive |
META-INF/container.xml |
Points a reading app at the real manifest |
EPUB/content.opf |
The manifest: every file in the book, plus the spine, the reading order |
EPUB/nav.xhtml |
EPUB 3's table of contents, itself an ordinary XHTML page |
EPUB/toc.ncx |
The older EPUB 2 table of contents, kept for readers that skip nav.xhtml |
EPUB/text/*.xhtml |
One file per chapter, title page and cover page |
EPUB/styles/*.css |
The stylesheet every chapter links to |
EPUB/media/* |
Images, including the cover |
That's what we found unzipping the file Pandoc wrote for converting Markdown to EPUB.
Renaming book.epub to book.zip and having every one of these files show up in Finder or File Explorer is a clean demonstration of what a file extension actually is: a label the operating system trusts, not a description of the bytes underneath it.
EPUB and PDF at a glance
EPUB stores reflowable text; PDF stores a fixed page. That one difference explains most of what changes when a file moves between them.
| EPUB | ||
|---|---|---|
| Compression | Lossless only | Lossy or lossless |
| Embedded metadata | Yes | Yes |
| Multiple images or pages | Yes | Yes |
| Selectable text | Yes | Yes |
| Encryption | Yes | Yes |
| Released | 2007 | 1993 |
| Developer | International Digital Publishing Forum | Adobe |
Both formats can hold hundreds of pages and both can be encrypted. Only one of them decides in advance where those pages break.
Why do page numbers disappear when you open an EPUB?
Because nothing in the file specifies a page size. An EPUB stores a continuous flow of XHTML, and the reading app breaks it into pages at whatever screen width and font size the reader picked, not at whatever the author saw while writing.
FileFlip's converter has to pick something when it turns that flow into a fixed-page PDF. It lays reflowable text out at 595 by 842 points, the point dimensions of A4 at 72 points per inch, with an 11-point default font and no control in the interface to change either one.
We ran the same book through that layout at four font sizes, changing nothing else about the page.
- 9pt11 pages
- 11pt16 pages, FileFlip's default
- 14pt26 pages
- 18pt44 pages
Same EPUB, same page box, only the font size changed. Measured with MuPDF's mudraw at each size; method below.
Page count nearly quadrupled between the smallest and largest setting, using the identical words on the identical page box. A page number on your phone means nothing on a printed copy or a different reader, because nothing in the file pins a page down. Any page count you see is the reading app's own guess, generated fresh each time it opens the book.
Where does the cover image live?
In the manifest, tagged twice for two different generations of reading software, not in some special cover slot in the archive.
Our test book's content.opf carries both markers. An EPUB 2 reader looks for <meta name="cover" content="..."> in the metadata block, matching an id in the manifest. An EPUB 3 reader looks for properties="cover-image" on the manifest item itself. Pandoc writes both, because plenty of reading apps still only check one.
Neither marker changes what the file actually is: the cover is an ordinary image sitting in EPUB/media/, placed on its own XHTML page at the start of the spine. Delete both markers and the image doesn't disappear. It just stops being flagged as the cover.
What breaks when you convert an EPUB to PDF?
The table of contents, mostly, and anything DRM-protected won't convert at all. The words, the images and the reading order all survive.
We converted our test EPUB with FileFlip's own epub>pdf route and checked the result with MuPDF's own inspector. The reading order held exactly: each chapter still starts on its own page. The outline, the list a PDF viewer's sidebar uses for jump-to-chapter navigation, came back empty. nav.xhtml and toc.ncx name every chapter and where it starts; neither one turns into a bookmark in the PDF.
| In the EPUB | After converting to PDF |
|---|---|
| Spine (reading order) | Preserved, pages come out in the same order |
| Chapter start (new XHTML file) | Preserved as a page break, but unlabeled |
nav.xhtml / toc.ncx (table of contents) |
Dropped, the PDF's own outline is empty |
Cover metadata (properties="cover-image") |
Dropped, the cover is just page one's image now |
| Reflow (no fixed page size) | Replaced with a fixed 595×842pt page the converter chooses |
This is the same trade our piece on what a conversion actually costs measures for other format pairs: something gets dropped whenever the destination has no field for what the source had, and a table of contents with nowhere to go is exactly that kind of loss. If you need chapter navigation to survive, convert EPUB to PDF and check the result in your PDF reader before deciding it's good enough.
A DRM-protected EPUB won't convert at all. Adobe's ADEPT scheme and most retailer encryption lock the actual chapter files inside the archive, so a converter handed an encrypted file has nothing readable to work with, on FileFlip or anywhere else.
How do you build an EPUB from Markdown?
Write the book as one Markdown file with a YAML title and author block at the top, then run it through FileFlip's md>epub converter.
- Start the file with a front matter block:
title:,author:, andlang:if the book isn't in English. - Use
#for each chapter heading. Pandoc splits the EPUB into one XHTML file per top-level heading on its own. - Convert MD to EPUB. There's no setting to pick; Pandoc handles the packaging. It reads Pandoc's own Markdown dialect either way, so footnotes and definition lists carry through even though the source file doesn't declare a dialect; which Markdown are you actually writing covers what that dialect adds over plain CommonMark.
One thing it can't do: pull in an image that lives in a separate file. FileFlip converts one file at a time, this Markdown document and nothing else, so a  reference to a file the converter never received comes back broken, and a cover-image: field pointing at one fails the conversion outright.
Base64-encoding an image directly into the Markdown as a data URI gets a picture through, since the image data then travels inside the text file itself. It won't work for cover-image: though; that field wants a real file path, and a data URI isn't one. The nearest thing to a real cover is putting that data-URI image as the first line of the book.
How we measured this
We wrote a three-chapter Markdown manuscript, about 10,000 words of placeholder paragraphs long enough to paginate meaningfully, with a YAML title, author and a plain PNG cover. Pandoc 3.10.2, the version FileFlip's WebAssembly build embeds, converted it to EPUB with the same standalone call our md>epub route makes.
For the PDF numbers, we reproduced FileFlip's own epub>pdf path by hand: Pandoc converts the EPUB to HTML first, then MuPDF lays that HTML out at a fixed page size before writing PDF pages, the same two-step conversion our worker code runs. We ran that layout step with MuPDF 1.28.2's mudraw at four font sizes (mutool draw -W 595 -H 842 -S <size>), holding the page box constant and changing only the font size, and read the page count back with mutool info. The table of contents check used mutool show <file> outline, which printed nothing for the converted PDF.
Real books vary more than one placeholder manuscript does. A novel with short paragraphs reflows differently than a reference book full of long ones, so treat 16 and 44 as an illustration of the effect, not a page count to expect from your own file.