If you write code for a living, you already have most of the tools you need to write a book. Version control, plain text, linters and CI pipelines work just as well on a manuscript as they do on a codebase. Word processors, on the other hand, tend to fight you: binary files, painful diffs and formatting that changes when you open the file on another machine.
This post walks through a simple, open workflow for writing a technical book (or a long guide) as plain Markdown, building ebook and PDF versions automatically, and catching problems before they reach your readers. It assumes basic comfort with Git and the command line.
The Project Structure
Keep the book in a Git repository, with one Markdown file per chapter. Numbered file names keep the order predictable:
my-book/
├── metadata.yaml
├── cover.jpg
├── chapters/
│ ├── 01-introduction.md
│ ├── 02-setup.md
│ └── 03-first-project.md
├── .vale.ini
└── .github/
└── workflows/
└── build.yml
The metadata.yaml file holds the book's title, author, language and other details that Pandoc reads when it builds the output:
title: "My Book Title"
author: "Your Name"
lang: en-US
Because everything is plain text, git diff shows exactly what changed in a chapter, branches let you try a different structure without risk, and your commit history becomes a free backup of every draft.
Building Outputs with Pandoc
Pandoc converts Markdown into almost any format. These commands build an EPUB, a PDF and a Word file from the same source:
EPUB for e-readers
pandoc metadata.yaml chapters/*.md -o book.epub \
--toc --toc-depth=2 --epub-cover-image=cover.jpg
PDF (requires a LaTeX engine such as XeLaTeX)
pandoc metadata.yaml chapters/*.md -o book.pdf \
--pdf-engine=xelatex --toc
DOCX, useful when an editor wants to comment in Word
pandoc metadata.yaml chapters/.md -o book.docx --toc
The shell expands chapters/.md in alphabetical order, which is why the numbered file names matter. The DOCX export is worth keeping: many editors and reviewers prefer tracked changes in Word, and you can bring their edits back into Markdown by hand or with a diff.
Linting Your Prose with Vale
We lint code, so why not prose? Vale is a command-line linter that checks text against style rules. A minimal .vale.ini looks like this:
StylesPath = styles
MinAlertLevel = suggestion
Packages = write-good
[*.md]
BasedOnStyles = Vale, write-good
Run vale sync once to download the style package, then run vale chapters/ to get warnings about passive voice, weak words, repeated phrases and similar issues. Treat the output as suggestions, not commands. It will not judge your argument, but it is very good at catching the same habits you repeat in every chapter.
For spelling and grammar, many authors pair Vale with a spell checker in their editor. Whatever you choose, run the checks before you ask anyone else to read the draft.
Automating the Build with GitHub Actions
A CI job guarantees that your book builds on a clean machine, and it gives you a fresh download after every push. Here is a minimal workflow:
name: build-book
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Pandoc
run: sudo apt-get update && sudo apt-get install -y pandoc
- name: Build EPUB
run: |
pandoc metadata.yaml chapters/*.md -o book.epub --toc
- name: Upload the build
uses: actions/upload-artifact@v4
with:
name: book
path: book.epub
If a chapter contains broken Markdown or a missing image, the job fails and you find out immediately, not on the day you try to publish. You can extend the workflow later to run Vale and to build the PDF as well.
Validating the EPUB
Before you upload an ebook anywhere, validate it. EPUBCheck is the reference validator for the EPUB format:
java -jar epubcheck.jar book.epub
Retailers can reject files with structural errors, and a validator tells you what is wrong in plain language. Make it a habit to run it on every release candidate.
Where Plain Text Stops Being Enough
This workflow handles writing, version control and file generation very well. It does not do everything. A few jobs still benefit from specialists:
• Developmental and copy editing. A fresh pair of eyes catches problems that no linter can, such as confusing explanations and gaps in the logic.
• Cover and interior design. A readable layout and a strong cover affect how a book looks next to others. Pandoc's default PDF styling is functional, not designed.
• ISBNs, metadata and distribution. Registering a book and getting it into stores involves paperwork and platform rules.
Some authors cover these steps with freelancers, and others use a publishing service. Services such as Miami Book Publishers are one option for the production and distribution side, so compare what each one includes, who keeps the rights and how royalties work before you sign anything. Your Markdown source stays useful either way, because every editor and designer can work from the exported files.
A Short Checklist
Before you call a draft finished, run through this list:
- Every chapter builds without errors in CI.
- Vale reports no warnings you haven't reviewed.
- The EPUB passes EPUBCheck.
- Code samples in the book have been run on a clean machine.
- At least one reader outside your team has gone through the draft.
- The cover, title and description match what the book actually covers. Wrapping Up Writing a book is a long project, and the same habits that keep a codebase healthy also help a manuscript: small commits, automated checks and regular builds. Start with one chapter, set up the pipeline once, and the rest becomes routine. Have you written a book or a long guide this way? I'd like to hear which tools you used and what you would change. Disclosure: I'm affiliated with Miami Book Publishers, which is mentioned above.
Top comments (0)