Version 1.8.0
Overview
Updated 5 min ago
@m2d/core: Core engine to convert extended MDAST to DOCX. Supports plugins for footnotes, images, lists, tables, and more. Designed for seamless Markdown-to-DOCX conversion.
✨ Features
- ⚡ Lightweight & Fast: Direct conversion from Markdown Abstract Syntax Trees (MDAST) into native OpenXML Word structures.
- 🌐 Dual-Runtime Compatibility: Runs 100% in-browser (
Blob, zero server required) and on server runtimes (Buffer,Uint8Arrayin Node.js, Next.js, Cloudflare Workers). - 📑 Section & Layout Control: Multi-section documents with individual page sizes, orientation (Portrait/Landscape), margins, headers, and footers.
- 🔌 Extensible Plugin Pipeline: Rich lifecycle hooks (
preprocess,inline,block,postprocess) for images, diagrams, math equations, and HTML. - 🛡️ Defensive & Resilient: Built-in warning deduplication (
warnOnce), safe error fallbacks, and non-mutating option handling. - 💾 Persistent Caching Engine: Multi-tiered cache (
@m2d/core/cache) using IndexedDB and in-memory caches with timestamped TTL and lock-free concurrency.
📦 Installation
$ pnpm add @m2d/core docxor
$ npm install @m2d/core docxor
$ yarn add @m2d/core docx🚀 Quick Start
Convert a Markdown string to a Word .docx file in just a few lines:
import { toDocx } from "@m2d/core";
import remarkParse from "remark-parse";
import remarkGfm from "remark-gfm";
import { unified } from "unified";
// 1. Parse Markdown into an MDAST tree
const markdown = "# Project Overview\n\nGenerated with **@m2d/core**.";
const mdast = unified().use(remarkParse).use(remarkGfm).parse(markdown);
// 2. Convert MDAST to a DOCX Blob (or 'buffer' on server)
const docxBlob = await toDocx(mdast, {
title: "Project Overview",
creator: "md2docx",
});
// 3. In the browser, trigger download or save
const url = URL.createObjectURL(docxBlob as Blob);
const a = document.createElement("a");
a.href = url;
a.download = "document.docx";
a.click();🔌 Official Plugins Ecosystem
@m2d/core stays lean by delegating domain-specific nodes to modular plugins. Install only what you need:
| Plugin | Package | Environment | Purpose |
|---|---|---|---|
| HTML | @m2d/html | Browser / Node | Parses inline HTML styling, <kbd>, <mark>, badges, and embeds |
| Image | @m2d/image | Browser | In-browser canvas rasterization for SVGs, URLs, and Base64 images |
| Image (Node) | @m2d/image-node | Server (Node.js) | Server-side image and SVG rasterization via sharp |
| Mermaid | @m2d/mermaid | Browser | Renders client-side Mermaid diagrams into SVG/PNG with auto-fixer |
| Mermaid (Node) | @m2d/mermaid-node | Server (Node.js) | Server-side DOM-less Mermaid diagrams via beautiful-mermaid |
| Math | @m2d/math | Browser / Node | Compiles LaTeX math formulas into native Word <m:oMath> equations |
| Table | @m2d/table | Browser / Node | Renders GFM tables with column alignments, borders, and header fills |
| List | @m2d/list | Browser / Node | Formats ordered, unordered, and nested hierarchical lists |
| MDAST Types | @m2d/mdast | Browser / Node | TypeScript types for extended MDAST AST nodes |
Using Plugins
import { toDocx } from "@m2d/core";
import { tablePlugin } from "@m2d/table";
import { imagePlugin } from "@m2d/image";
const docxBlob = await toDocx(mdast, {}, {
plugins: [tablePlugin(), imagePlugin()],
});📜 API Reference
toDocx(astInputs, docxProps?, defaultSectionProps?, outputType?)
function toDocx(
astInputs: Root | { ast: Root; props?: ISectionProps }[],
docxProps?: IDocxProps,
defaultSectionProps?: IDefaultSectionOptions,
outputType?: "blob" | "buffer" | "arraybuffer",
): Promise<Blob | Buffer | ArrayBuffer | Uint8Array>;Parameters
astInputs: An MDASTRootnode, or an array of section descriptors{ ast: Root, props?: ISectionProps }[]for multi-section documents.docxProps(optional): Global document properties passed todocx.Document(title, author, subject, styles, etc.).defaultSectionProps(optional): Layout and conversion configuration applied to sections:useTitle(boolean, default:true): Maps top-level# Headingto Word'sTitlestyle and demotes nested headings proportionally.plugins(IPlugin[]): Array of conversion plugins.trimInnerSpaces(boolean, default:true): Normalizes repeated whitespace in text runs.- Plus standard
docxISectionOptions(margins, paper size, orientation, headers, footers).
outputType(optional, default:'blob'): Target binary format ("blob","buffer", or"arraybuffer").
📚 Deep Dive Guides & Architecture
Explore our dedicated documentation guides for advanced configurations and internal know-how:
- ⚡ Caching Architecture Guide: Multi-tiered cache design, why TTL avoids write-amplification, lock-free IndexedDB concurrency, and
shouldCachevalidation. - 🔌 Plugin Authoring Guide: How to create custom plugins, hook into
preprocess,block,inline, andpostprocesslifecycles, and handle errors. - 📑 Sections & Layout Guide: Crafting multi-section documents, landscape pages, custom margins, and heading hierarchy.
License
This library is licensed under the MIT open-source license.
with 💖 by Mayank Kumar Chaudhari