Kindle-Ready eBooks from Markdown

I've found creating eBooks from Markdown to be a nice way to learn away-from-computer. Here are a few notes on how to nicely setup a workflow for generating Kindle-ready EPUBs from Markdown files.

The Setup

Install pandoc via Homebrew:

brew install pandoc

Then, for example, add a script to your package.json (I'm assuming here you are using a Node.js project with pnpm, but similar instructions apply to different setups, there is very little actually Node.js-specific here):

{
  "scripts": {
    "book:epub": "pandoc book/*.md --epub-cover-image=book/cover.png -t epub3 --metadata uuid='a3f1c820-4b2e-4d91-8c77-1e9f3d5b6a04' --metadata author='AUTHOR' --metadata title='TITLE' -o 'TITLE - AUTHOR.epub'"
  }
}

Run it with, for example, pnpm book:epub.

What Each Flag Does

book/*.md — pandoc globs your chapter files in filename order, so a naming convention like 01-intro.md, 02-chapter.md keeps things tidy.

--epub-cover-image — points to your cover art. JPEG is recommended, but PNG works fine too. I'd suggest using a 3:4 aspect ratio, e.g., 1200x1600px, as that will work well on most eBook readers. You can use e.g. Gemini or ChatGPT to generate the image.

-t epub3 — targets EPUB 3, which Kindle handles well.

--metadata uuid — EPUB requires a unique identifier. Generate a fresh one for every new book at uuidgenerator.net — never reuse one between different titles (the point is that it is unique). This seems to be the most important detail for the Send to Kindle service to work at all.

--metadata title and --metadata author — technically optional, but they populate the eBook's metadata fields and make the Send to Kindle app behave more reliably. Also pandoc will use the title for the table of contents, so it's worth setting.

Naming the Output File

Avoid a generic name like book.epub. The Send to Kindle desktop app will not picking up titles or author from metadata. Use something descriptive:

'TITLE - AUTHOR.epub'

Where TITLE might be PyTorch Notes. Though actually it seems if you use the web client to send (see below), it is best to go with TITLE.epub as the filename is used as displayed title (even when the metadata title is set). So to give a full example: PyTorch Notes.epub.

AI-Generated Content

Suggestions:

  • Ask for each chapter as a separate file, drop them into your book/ directory, and run the script. - Make sure to request files to be named like e.g. 001-intro.md, 002-chapter.md to ensure alphabetical ordering and an easier time with pandoc globs.
  • Ask the LLM to generate a single markdown file per source code file. Ask for code snippets and specific extra chapters. Ask for background. Questions for reflection. Multiple choice questions at the end of the chapter. (And so on.)

Sending to Kindle

Once you have the .epub, the easiest route is the Send to Kindle. You can either download the desktop app or use the web version.