javascript-today

Markdown to ebook

From Markdown to Ebook: A Practical Guide to Pandoc and Ibis Next

Published · Ebook Publishing · 12 min read


If you’ve ever written documentation, a technical guide, or even a book draft in Markdown, you’ve probably wondered at some point: how do I turn this into something people can actually read on a Kindle or an iPad? The good news is that the Markdown-to-ebook pipeline is mature, well-supported, and entirely open source. The better news is that your content is already in the best possible format to start from.

This post is a deep dive into two of the best open source tools for the job — Pandoc and Ibis Next — covering how each works, when to use which, and everything you need to know to go from a folder of .md files to a polished, distributable ebook.


Why Markdown is the Ideal Starting Point

Before we get into the tools, it’s worth appreciating why Markdown is such a strong foundation for ebook creation.

Markdown is plain text. That means it works with version control, it’s readable without any special software, and it’s completely portable across tools and operating systems. Unlike Word documents or proprietary formats, a Markdown file in 2025 will open fine in 2045. It also maps naturally to the structure of a book — headings become chapters, subheadings become sections, and your content hierarchy is already baked in.

The ebook standard most tools target is EPUB, an open format maintained by the W3C that is supported by virtually every e-reader and reading app — Apple Books, Kobo, Nook, and (as of 2022) even Kindle. EPUB is essentially a zip file containing HTML, CSS, and metadata. Since Markdown converts cleanly to HTML, the path from Markdown to EPUB is a natural one.


Pandoc: The Universal Converter

Pandoc is the gold standard for document conversion. It was created by philosopher and programmer John MacFarlane and has been under active development since 2006. It is, at its core, a command-line tool that converts between dozens of formats — but for ebook creators, it is arguably the most powerful Markdown-to-EPUB tool in existence.

What makes Pandoc special

The key insight behind Pandoc is that it doesn’t just do a surface-level format swap. It parses your document into an internal abstract syntax tree (AST), then renders that AST into the target format. This means it understands the structure of your document rather than just its syntax — and it allows a rich set of transformations to happen in between.

For ebook work, this matters because EPUB has real structural requirements: a table of contents, spine ordering, metadata, navigation documents. Pandoc handles all of this automatically.

Installation

Pandoc is available on all major platforms. On macOS with Homebrew:

brew install pandoc

On Ubuntu or Debian:

sudo apt install pandoc

On Windows, download the installer from pandoc.org. For PDF output, you’ll also need a LaTeX distribution — texlive-xetex on Linux, MacTeX on macOS, or MiKTeX on Windows. For EPUB output alone, LaTeX is not required.

Your first EPUB in one command

If you have a single Markdown file, the conversion is remarkably simple:

pandoc mybook.md -o mybook.epub

That’s it. Pandoc will generate a valid EPUB 3 file with a basic table of contents derived from your heading structure.

For a more realistic scenario — a book split across multiple chapter files — you combine them in order:

pandoc 
  chapter01.md chapter02.md chapter03.md -o mybook.epub

Pandoc joins them into a single document, respecting heading levels across files.

Adding metadata with YAML front matter

A bare EPUB has no title, author, or language metadata. You can add all of this using a YAML metadata block, either at the top of your first Markdown file or in a dedicated metadata.yaml file:

---
title: "The Art of Clear Writing"
author: "Jane Doe"
date: "2025"
lang: en-US
rights: "© 2025 Jane Doe. All rights reserved."
---

Pass it to Pandoc like this:

pandoc metadata.yaml chapter01.md chapter02.md -o mybook.epub

Cover images

A cover image is essential for any ebook you intend to distribute. Pandoc accepts it as a flag:

pandoc metadata.yaml chapter01.md chapter02.md \
  --epub-cover-image=cover.jpg \
  -o mybook.epub

The image should be a JPEG or PNG, and ideally at least 1600 × 2400 pixels for a good-looking cover on high-DPI screens.

Custom CSS for styling

By default, Pandoc applies a minimal stylesheet. For most purposes you’ll want to bring your own CSS to control fonts, spacing, code block styles, and more:

pandoc metadata.yaml chapter01.md chapter02.md \
  --epub-cover-image=cover.jpg \
  --css=styles.css \
  -o mybook.epub

A simple starting styles.css for an ebook might look like this:

body {
  font-family: Georgia, serif;
  font-size: 1em;
  line-height: 1.7;
  margin: 0 5%;
}

h1, h2, h3 {
  font-family: "Helvetica Neue", Helvetica, sans-serif;
  line-height: 1.25;
}

code, pre {
  font-family: "Courier New", monospace;
  font-size: 0.85em;
  background: #f4f4f4;
}

pre {
  padding: 1em;
  overflow-x: auto;
  border-left: 3px solid #ccc;
}

Table of contents

Pandoc can generate a proper navigable table of contents from your heading structure:

pandoc metadata.yaml chapter01.md chapter02.md \
  --toc \
  --toc-depth=2 \
  --epub-cover-image=cover.jpg \
  --css=styles.css \
  -o mybook.epub

--toc-depth controls how many heading levels appear in the contents — 2 means H1 and H2.

Syntax highlighting for technical books

If your book contains code, Pandoc’s built-in syntax highlighting is excellent. You can choose from a range of themes:

pandoc metadata.yaml chapter01.md \
  --highlight-style=tango \
  -o mybook.epub

Available themes include pygments, tango, espresso, zenburn, kate, monochrome, breezedark, and haddock. To see what you have available:

pandoc --list-highlight-styles

Generating PDF alongside EPUB

One of Pandoc’s most powerful features is the ability to produce multiple output formats from the same source. For PDF, Pandoc routes through LaTeX:

pandoc metadata.yaml chapter01.md chapter02.md \
  --toc \
  --pdf-engine=xelatex \
  -V geometry:margin=1in \
  -o mybook.pdf

The -V geometry:margin=1in sets the page margins via the LaTeX geometry package. You can control font, paper size, line spacing, and much more through LaTeX variables.

For any serious book project, a well-organised directory makes a big difference:

mybook/
├── content/
│   ├── 01-introduction.md
│   ├── 02-getting-started.md
│   ├── 03-core-concepts.md
│   └── 04-conclusion.md
├── assets/
│   ├── cover.jpg
│   └── styles.css
├── metadata.yaml
└── build.sh

Your build.sh script then handles the full conversion:

#!/bin/bash
pandoc \
  metadata.yaml \
  content/01-introduction.md \
  content/02-getting-started.md \
  content/03-core-concepts.md \
  content/04-conclusion.md \
  --toc \
  --toc-depth=2 \
  --epub-cover-image=assets/cover.jpg \
  --css=assets/styles.css \
  --highlight-style=tango \
  -o mybook.epub

echo "Build complete: mybook.epub"

Make it executable with chmod +x build.sh and run it with ./build.sh. You can extend this pattern with make for more sophisticated dependency tracking.

Advanced: filters and Lua scripting

Pandoc’s deepest power comes from its filter system. Filters are scripts that intercept the AST between parsing and rendering, letting you transform content programmatically. The most approachable filter language is Lua, which is built into Pandoc:

-- replace-callouts.lua
-- Convert blockquotes starting with [!NOTE] into styled divs
function BlockQuote(el)
  local first = el.content[1]
  if first and first.t == "Para" then
    local text = pandoc.utils.stringify(first)
    if text:match("^%[!NOTE%]") then
      return pandoc.Div(el.content, {class = "callout-note"})
    end
  end
  return el
end

Apply it with:

pandoc chapter01.md --lua-filter=replace-callouts.lua -o mybook.epub

This is how you can implement custom callouts, admonitions, figure captions, and other structural elements beyond standard Markdown.

Pandoc’s honest limitations

Pandoc is powerful but not effortless. The learning curve is real — the manual is long, and getting a beautifully styled PDF in particular requires investing time in LaTeX configuration. CSS styling for EPUB is straightforward, but fine-tuning takes iteration. Pandoc is also not a GUI tool, which means you need to be comfortable on the command line and ideally with shell scripting.

For authors who just want to write and publish without learning a tool ecosystem, that’s a significant ask. Which brings us to the alternative.


Ibis Next: Purpose-Built for Ebook Creators

Ibis Next takes a very different philosophy to Pandoc. Where Pandoc is a universal converter, Ibis Next is a focused tool built specifically for the Markdown-to-ebook workflow. It originated as the “Ibis” project by Mohamed Said and was forked and significantly extended by the Hi-Folks team to add EPUB support, HTML output, and compatibility with modern PHP versions.

What Ibis Next prioritises

Ibis Next is optimised for a specific workflow: you write chapters in Markdown files, configure a few settings, and run a single command to get a polished ebook. It handles theming, table of contents generation, code syntax highlighting, and cover images out of the box with sensible defaults. The trade-off is that it does far fewer things than Pandoc — but the things it does, it does with minimal friction.

Installation

Ibis Next is a PHP package installed via Composer. If you don’t have Composer installed, get it from getcomposer.org. Then install Ibis Next globally:

composer global require hi-folks/ibis-next

Make sure Composer’s global bin directory is in your PATH. On macOS and Linux, add this to your shell profile:

export PATH="$HOME/.composer/vendor/bin:$PATH"

Verify the installation:

ibis-next --version

Setting up a new project

Initialise a new project directory with:

mkdir my-ebook && cd my-ebook
ibis-next init

This creates the following structure:

my-ebook/
├── assets/
│   ├── fonts/
│   ├── cover.jpg          ← replace with your own cover
│   ├── epub.css           ← styles for EPUB output
│   └── theme-light.css    ← styles for PDF output (light theme)
├── content/
│   └── 01-introduction.md ← your chapter files go here
└── ibis.php               ← project configuration

Configuring your book

The ibis.php file is the heart of your project configuration. It’s a simple PHP array:

<?php

return [
    'title'       => 'My Book Title',
    'author'      => 'Jane Doe',
    'description' => 'A short description of what this book covers.',
    'cover'       => 'assets/cover.jpg',
    'output'      => 'export',
    'theme'       => 'light',       // 'light' or 'dark' for PDF
    'header'      => 'title',       // page header style for PDF
    'font'        => [
        'size'   => 14,
        'family' => 'SourceSerif4',
    ],
    'table_of_contents' => [
        'enabled' => true,
        'depth'   => 2,
    ],
];

This is notably simpler than crafting a Pandoc command with a dozen flags.

Writing your chapters

Each chapter lives in its own Markdown file inside the content/ directory. Ibis Next processes them in alphabetical order, which is why numeric prefixes work well:

content/
├── 01-introduction.md
├── 02-why-this-matters.md
├── 03-core-concepts.md
├── 04-practical-examples.md
└── 05-conclusion.md

Each file can include a YAML front matter block to set the chapter title:

---
title: "Core Concepts"
---

## What We're Building Towards

In this chapter we'll cover the foundational ideas that underpin everything else in the book...

Generating your ebook

Building the EPUB is a single command:

ibis-next epub

The output lands in the export/ directory as my-book-title.epub. For PDF:

ibis-next pdf

For an HTML version:

ibis-next html

You can generate all three at once:

ibis-next epub && ibis-next pdf && ibis-next html

Themes: light and dark

One of Ibis Next’s nicest built-in features is theme support for PDF output. Setting 'theme' => 'dark' in ibis.php applies a dark background style, which works particularly well for technical books and developer documentation. The light theme is clean and readable for general prose.

For EPUB, styling is handled by assets/epub.css, which you can edit freely. Because EPUB is HTML under the hood, standard CSS applies without limitation.

Code syntax highlighting

Code blocks in your Markdown are automatically syntax-highlighted in the output. Ibis Next uses the underlying CommonMark parser and applies highlighting via CSS classes. For technical writing, this works reliably without any extra configuration.

Ibis Next’s limitations

Ibis Next requires PHP and Composer — a dependency stack that feels natural to PHP developers but may be surprising to authors coming from a different background. It also has a narrower output target: PDF, EPUB, and HTML only. No DOCX, no LaTeX, no MOBI.

It lacks Pandoc’s academic features — no bibliography support, no LaTeX math, no cross-reference system. For a technical reference book or academic work, those gaps matter. For a general non-fiction book, a developer guide, or a self-published title, they likely don’t.


Head-to-Head: Choosing the Right Tool

Both tools solve the same core problem, but they inhabit very different niches. Here’s how the key decision points break down:

For technical and academic authors

Pandoc is the clear choice. Its support for LaTeX math, BibTeX citations, cross-references via pandoc-crossref, and custom Lua filters makes it the right tool for anything that goes beyond prose. If your book has equations, a bibliography, or needs to be submitted to a publisher with specific formatting requirements, Pandoc can meet those demands in ways Ibis Next simply cannot.

For non-technical authors and first-time publishers

Ibis Next wins on accessibility. The configuration is minimal, the output is good-looking by default, and the workflow is intuitive: write chapters, run one command, get an ebook. You don’t need to understand flags, LaTeX variables, or CSS specificity to get a result you’re proud of.

For developers writing documentation or guides

Both work well, but their strengths differ. Pandoc gives you more control over output and integrates naturally into automated build pipelines and CI/CD workflows. Ibis Next gives you better defaults out of the box, especially for PDF, and requires less scaffolding to get started.

For multi-format publishing

Pandoc is unmatched. If you need EPUB, PDF, DOCX, and an HTML website from the same Markdown source, Pandoc handles all of it. Ibis Next is limited to the three formats it was designed for.


A Practical Workflow: Combining Both Tools

There is no rule that says you have to choose one or the other. A sensible workflow for many projects is to use Ibis Next during writing — because its fast feedback loop (run ibis-next epub, preview, adjust) is pleasant for iteration — and then switch to Pandoc for final output when you need fine-grained control over the finished product.

Similarly, many authors use Pandoc for EPUB generation and then open the result in Calibre to edit metadata, preview the ebook visually, and export a Kindle-compatible file. Pandoc creates the structure; Calibre refines the presentation and handles distribution format conversion.


Tips for Better Output from Either Tool

Regardless of which tool you use, the quality of your Markdown source has a big effect on the quality of your ebook output. A few practices make a measurable difference:

Use heading levels consistently. H1 (#) should be used for chapter titles only. H2 (##) for sections within a chapter. H3 (###) for subsections. Skipping levels confuses both tools’ table of contents generation.

Keep one file per chapter. Both Pandoc and Ibis Next handle multi-file input gracefully, and it makes your project much easier to manage than one enormous Markdown file.

Describe all images with alt text. EPUB accessibility standards require it, and both tools pass the alt text through to the output. A screenreader-friendly ebook is also a better ebook.

Test on a real device early. EPUB rendering varies between e-readers. What looks good in Calibre’s viewer may look different on a Kobo or in Apple Books. Send yourself a draft EPUB early in the process, before you’ve committed to a styling approach.

Keep external links absolute. Internal links between sections work well with anchor syntax, but external links should always be full URLs. Both tools handle them correctly, and readers expect to tap a link and reach a real URL.


Getting Your Ebook to Readers

Once you have a finished EPUB, distribution is straightforward:

  • Amazon KDP accepts EPUB directly (they convert it to their internal format). Upload via kdp.amazon.com.
  • Apple Books accepts EPUB via iTunes Connect or the Books app on macOS.
  • Kobo Writing Life, Draft2Digital, and Smashwords all accept EPUB and distribute to multiple retailers.
  • Gumroad and Lemon Squeezy let you sell directly to readers — just upload the EPUB as a digital download.

For a Kindle-specific file (MOBI or KFX), the easiest path is to upload your EPUB to KDP and let Amazon handle the conversion, or to use Amazon’s free Kindle Previewer app to convert locally before uploading.


Conclusion

Markdown is an exceptional foundation for ebook writing. It keeps you focused on content, plays well with version control, and converts cleanly to the formats readers actually use. The two tools explored here — Pandoc and Ibis Next — represent two different but equally valid approaches to that conversion.

Pandoc is the powerhouse: endlessly configurable, format-agnostic, and capable of producing everything from a paperback-ready PDF to a polished EPUB with a single command (once you’ve learned its flags). Ibis Next is the focused alternative: fewer options, better defaults, and a gentler on-ramp for authors who want to publish rather than configure.

For most authors starting out, Ibis Next offers the fastest path to a finished product. For authors who need fine-grained control — technical writers, academics, developers building automated publishing pipelines — Pandoc is worth every minute of the learning curve.

Either way, your content is in the right format. The rest is just picking the right tool and running a command.


Further reading: the Pandoc EPUB documentation and the Ibis Next GitHub repository are both excellent starting points for going deeper.