npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

md-to-epub

v1.1.1

Published

A TypeScript CLI tool to convert markdown files to EPUB format

Readme

md-to-epub

A TypeScript CLI tool to convert markdown files to EPUB format for e-readers. Supports single file conversion and bulk processing with extensive markdown features including images, footnotes, tables, code blocks, and more.

Features

  • Comprehensive Markdown Support: Tables, code blocks, blockquotes, lists, and more
  • 📷 Image Embedding: Automatically embeds images referenced in markdown
  • 📝 Footnotes: Full support for markdown footnotes
  • 📚 Bulk Conversion: Convert entire directories of markdown files
  • ⚙️ Configuration Files: Use .md-to-epubrc files for project-wide settings
  • 🎨 Styled Output: Professional EPUB formatting with customizable CSS
  • 🔧 CLI & Programmatic API: Use as a command-line tool or import into your projects

Installation

Global Installation

npm install -g md-to-epub

Local Installation

npm install md-to-epub

Usage

Command Line

Basic Usage

Convert a single markdown file:

md-to-epub input.md

This will create output/input.epub using default settings.

Specify Output Path

md-to-epub input.md -o mybook.epub

Set Metadata

md-to-epub input.md \
  --author "Jane Doe" \
  --title "My Great Book" \
  --language en \
  --publisher "My Publisher"

Include Cover Image

md-to-epub input.md --cover ./cover.jpg

Bulk Conversion

Convert all markdown files in a directory:

md-to-epub ./content-folder

Recursively process subdirectories:

md-to-epub ./content-folder --recursive

Specify output directory for bulk conversion:

md-to-epub ./content-folder --output-dir ./ebooks

Multi-Chapter Books

Combine multiple markdown files into a single EPUB with chapters:

md-to-epub chapter1.md chapter2.md chapter3.md --chapters -o book.epub

Combine all markdown files in a directory as chapters:

md-to-epub ./chapters-folder --chapters -o complete-book.epub

Recursively find and combine chapters:

md-to-epub ./book-project --chapters --recursive -o complete-book.epub

Configuration File

Create a .md-to-epubrc file in your project directory or home directory to set default options:

JSON format:

{
  "author": "Jane Doe",
  "language": "en",
  "publisher": "My Publishing House",
  "outputDir": "./ebooks",
  "rights": "Copyright © 2025 Jane Doe"
}

INI format:

author = Jane Doe
language = en
publisher = My Publishing House
outputDir = ./ebooks
rights = Copyright © 2025 Jane Doe

The configuration file will be automatically loaded from:

  1. Current directory (.md-to-epubrc)
  2. Parent directories (searching upward)
  3. Home directory (~/.md-to-epubrc)

CLI options will override configuration file settings.

Programmatic Usage

import { convertMarkdownToEpub, convertMarkdownFilesToChapters, loadConfig } from 'md-to-epub';

// Convert single file
await convertMarkdownToEpub({
  inputPath: './content/chapter1.md',
  outputPath: './output/chapter1.epub',
  config: {
    author: 'Jane Doe',
    title: 'Chapter 1',
    language: 'en',
  },
});

// Convert multiple files to chapters in single EPUB
await convertMarkdownFilesToChapters(
  ['./ch1.md', './ch2.md', './ch3.md'],
  './output/book.epub',
  {
    author: 'Jane Doe',
    title: 'Complete Book',
    language: 'en',
  }
);

// Use configuration file
const config = loadConfig({ author: 'Override Author' });
await convertMarkdownToEpub({
  inputPath: './content/chapter1.md',
  config,
});

// Bulk conversion (separate EPUBs)
import { convertDirectory } from 'md-to-epub';

const outputFiles = await convertDirectory(
  './content',
  { author: 'Jane Doe', language: 'en' },
  true // recursive
);
console.log('Created:', outputFiles);

CLI Options

| Option | Description | Default | |--------|-------------|---------| | <input...> | Input markdown file(s) or directory | (required) | | -o, --output <path> | Output EPUB file path | output/<filename>.epub | | -d, --output-dir <dir> | Output directory for bulk conversion | ./output | | -r, --recursive | Process directories recursively | false | | --chapters | Combine multiple files as chapters in single EPUB | false | | -a, --author <name> | Book author name | Unknown Author | | -t, --title <title> | Book title (overrides H1 from markdown) | From first H1 or filename | | -l, --language <code> | Language code (e.g., en, es, fr) | en | | -p, --publisher <name> | Publisher name | - | | -c, --cover <path> | Path to cover image | - | | --description <text> | Book description | - | | --rights <text> | Copyright/rights statement | All rights reserved | | --identifier <id> | Unique identifier | Auto-generated UUID |

Supported Markdown Features

  • Headings (H1-H6)
  • Paragraphs with proper text flow
  • Emphasis: italic, bold, bold-italic
  • Lists: Ordered and unordered
  • Links: Internal and external
  • Internal Links (Wikilinks): Cross-references between chapters
  • Images: Local files (automatically embedded)
  • Code: Inline code and fenced code blocks
  • Blockquotes
  • Tables
  • Horizontal rules
  • Footnotes: [^1] with definitions

Footnotes Example

This is a paragraph with a footnote[^1].

Another paragraph with another footnote[^note].

[^1]: This is the first footnote.
[^note]: This is a named footnote.

Images

Images are automatically embedded in the EPUB:

![Alt text](./images/diagram.png)
![Cover](../cover.jpg "Image title")

Local image paths are resolved relative to the markdown file.

Internal Links (Wikilinks)

When converting multiple markdown files into a single EPUB with chapters, you can use wikilink syntax to create cross-references between chapters:

See [[chapter2]] for more details.
See [[Chapter 2: The Investigation|the investigation]] for more details.
See [[chapters/chapter2|the analysis]].

How it works:

  • [[target]] - Creates a link using the target as both the link and display text
  • [[target|display text]] - Creates a link to target with custom display text

Link resolution (Obsidian-style):

The tool supports multiple matching strategies to find the target chapter:

  1. Filename match: [[chapter2]] matches chapter2.md
  2. Path match: [[chapters/chapter2]] matches chapters/chapter2.md
  3. Title match: [[Chapter 2: The Investigation]] matches the chapter with that title
  4. Basename from path: [[chapter2]] matches any file ending with chapter2.md regardless of directory

If the target matches an included chapter using any of these strategies, it creates a clickable link. Otherwise, it converts to plain text (just the display text).

Examples:

<!-- Links to an included chapter - multiple ways -->
As discussed in [[chapter1]], we found something unusual.
Reference [[chapters/chapter2|the data analysis]] from the investigation.
Continue reading in [[Chapter 3: The Revelation|the final chapter]].

<!-- Links to non-included files become plain text -->
The [[old research facility]] was closed years ago.
Consult [[Dr. Williams]] for more information.

In the EPUB output:

  • [[chapter1]] → clickable link to Chapter 1 (filename match)
  • [[chapters/chapter2|the data analysis]] → clickable link showing "the data analysis" (path match)
  • [[Chapter 3: The Revelation|the final chapter]] → clickable link showing "the final chapter" (title match)
  • [[old research facility]] → plain text "old research facility"
  • [[Dr. Williams]] → plain text "Dr. Williams"

This feature is particularly useful for:

  • Creating a connected narrative across multiple chapters
  • Cross-referencing related content
  • Maintaining wiki-style documentation in EPUB format

Output Structure

The generated EPUB follows the EPUB 3.0 standard and includes:

  • Proper EPUB structure: mimetype, META-INF/container.xml, content.opf, toc.ncx
  • Embedded images: All referenced images are included
  • Styled content: Professional CSS styling for optimal reading experience
  • Metadata: Title, author, language, publisher, etc.
  • Navigation: Table of contents based on document structure

Examples

Example 1: Simple Conversion

md-to-epub article.md

Example 2: Book with Metadata

md-to-epub book.md \
  --title "The Complete Guide" \
  --author "John Smith" \
  --publisher "Tech Books Publishing" \
  --cover ./cover.png \
  --description "A comprehensive guide to everything"

Example 3: Bulk Conversion with Config

Create .md-to-epubrc:

{
  "author": "John Smith",
  "publisher": "Tech Books Publishing",
  "language": "en",
  "outputDir": "./ebooks"
}

Then run:

md-to-epub ./chapters --recursive

Development

Build from Source

git clone https://github.com/yourusername/md-to-epub.git
cd md-to-epub
npm install
npm run build

Run Locally

npm start -- input.md -o output.epub

Project Structure

md-to-epub/
├── src/
│   ├── cli.ts              # CLI entry point
│   ├── config.ts           # Configuration management
│   ├── converter.ts        # Main conversion logic
│   ├── epub-generator.ts   # EPUB file generation
│   ├── markdown-parser.ts  # Markdown parsing & rendering
│   ├── types.ts            # TypeScript type definitions
│   └── index.ts            # Public API exports
├── package.json
├── tsconfig.json
└── README.md

License

MIT License - Copyright © 2025 Aster Haven

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Troubleshooting

Images Not Appearing

  • Ensure image paths are correct relative to the markdown file
  • Check that image files exist and are readable
  • Supported formats: JPEG, PNG, GIF, SVG

EPUB Validation

The generated EPUBs follow the EPUB 3.0 standard. You can validate them using:

Common Issues

Issue: "Cannot find module" errors

  • Solution: Run npm install to install dependencies

Issue: Permission denied when running globally

  • Solution: Use sudo npm install -g md-to-epub or configure npm to use a local prefix

Issue: Output directory doesn't exist

  • Solution: The tool creates output directories automatically, but ensure parent directories are writable

Acknowledgments

Built with: