Command line

Markdown to Word CLI

Turn a .md file into a real .docx — Word heading styles, editable tables, native numbering, equation objects — with one command. No Pandoc, no LaTeX distribution, no 2 GB install. Pure JavaScript on Node 20 or newer, identical on macOS, Linux and Windows.

Not on npm yet. The CLI is finished and its 184 tests pass, but it has not been published: the conversion engine it depends on has an unresolved licence question, and a public package that depends on an unpublished private one would not install. So the commands below are the commands you will run when it ships, not commands that work today — npx @mdtodocx/cli currently returns a 404 from the registry, and there is no public repository to install from either. We would rather write that plainly than point you at a URL that does not exist. Meanwhile the same engine runs in your browser on the Markdown to Word converter, and the package name is being reserved so the command below is the one that will be correct.

Install (once it is published)

npx @mdtodocx/cli file.md            # no install at all
npm i -g @mdtodocx/cli               # then: mdtodocx file.md
npm i -D @mdtodocx/cli               # then: npx mdtodocx file.md

The command is md2word; the package is scoped as @mdtodocx/cli. If you ever see an unscoped md2word package on npm, check where it points before installing it — we publish under the scope, and the unscoped name is not ours.

The commands

mdtodocx input.md -o output.docx              # Word, the default
mdtodocx input.md -o output.pdf               # PDF, needs a headless Chromium
md2word README.md --to html                  # standalone print-ready HTML
md2word "docs/*.md" --out-dir dist/          # batch a folder
md2word doc.docx --to md                     # Word back to Markdown
cat answer.md | md2word --to docx > out.docx  # stdin to stdout

The direction is inferred from the extensions: .md in means Word out, .docx or .html in means Markdown out. Both --to and the extension of -o override the guess, and if the two disagree the explicit --to wins. A glob is expanded by the CLI itself rather than relying on the shell, so "docs/*.md" behaves the same in PowerShell as in bash when you quote it.

Options

FlagDefaultEffect
-o, --output <file>next to the inputDestination. Single input only.
--out-dir <dir>—Destination directory for a batch. Created if missing.
-t, --to <format>inferreddocx, pdf, html, md.
--font <name>CalibriBody and heading font.
--size <pt>11Body font size.
--paper <size>A4A4, Letter, Legal.
--tocoffWord table-of-contents field.
--number-headingsoff1, 1.1, 1.1.1 bound to the heading styles.
--page-numbersoffPage numbers in the footer.
--mathoff$…$ and $$…$$ become native Word equations (OMML).
--mermaidoffRender mermaid fences. Needs @mermaid-js/mermaid-cli.
--reference-doc <f>—Copy styles.xml from an existing .docx, like Pandoc's flag of the same name.
--css <file>—Extra stylesheet for the HTML and PDF output.
--no-signaturefooter onRemove the "Converted with MDtoDOCX" footer.
--prooffTurn every fidelity switch on at once.
--max-remote-images <n>unlimitedCap remote image downloads.
-q, --quietoffNo per-file summary. Errors still print.
--jsonoffMachine-readable result on stdout.

Exit codes and error output

CodeMeaning
0Every file converted.
1The command was valid but a conversion failed.
2Bad arguments: unknown flag, bad value, missing input.

Separating "you typed it wrong" from "the conversion failed" is what makes the tool usable in a Makefile or a CI job: a 2 means stop and fix the pipeline, a 1 means look at the document. Errors are one line plus an actionable hint:; stack traces never reach the terminal.

Pipes, batches and scripting

When bytes are being written to stdout, as in cat x.md | md2word > out.docx, the human-readable summary is redirected to stderr so it can never corrupt the document. That one rule is what makes the CLI safe inside a shell pipeline. For anything scripted, add --json and you get a single object with ok, the tool version, a files array carrying the input path, output path, format, byte count, per-file warnings and metadata (title, word count, heading count, image count, equation count, front matter), an errors array, and durationMs. A batch keeps going after a file fails and reports the failure in errors while still writing the ones that worked, so a folder of a hundred documents is not held hostage by one broken table.

Warnings are never swallowed. A skipped remote image, an unrendered diagram, an equation that could not be parsed — each produces a named warning attached to the file it came from, both in the terminal summary and in the JSON. Nothing degrades quietly.

The two optional dependencies

PDF is produced by printing the HTML output with a headless Chromium, which is deliberately not bundled — it would add hundreds of megabytes to a text converter. Install playwright (then npx playwright install chromium) or puppeteer as a dev dependency. Without one, --to pdf fails with an explicit message pointing you at --to html plus your browser's "Print to PDF"; it never writes a broken file. Mermaid works the same way: --mermaid shells out to mmdc from @mermaid-js/mermaid-cli, and without it diagrams stay as code blocks and the CLI prints a note saying exactly that.

How it relates to everything else here

The CLI, the Markdown to Word MCP server, the Markdown to Word skill and this website all run the same conversion engine, so a document converted in a terminal is byte-for-byte comparable to one converted in a browser tab. The difference is the entry point: the CLI is for scripts and CI, the MCP server is for AI agents that need to hand a user a file, and the website is for one document right now. Free and Pro tiering belongs to the hosted service described on pricing; a locally installed CLI runs the whole engine with no entitlement check, so every flag works. If you are migrating from Pandoc, the flag-by-flag mapping is on Markdown to Word with Pandoc, and the Python equivalents are compared on Markdown to PDF with Python.

Markdown to Word CLI: frequently asked questions

Can I install the Markdown to Word CLI today?
No. It is built and tested but not published to npm yet, because the shared conversion engine's licence has to be settled first. Running npx @mdtodocx/cli right now fails at the registry. Use the browser converter until it lands.
Which package name will it use on npm?
The scoped package @mdtodocx/cli, installing a command called md2word. It will not be published as the unscoped md2word name, so treat any unscoped package of that name as unrelated to this project.
Does the CLI need Pandoc or a LaTeX distribution?
No. It is pure JavaScript with a single runtime dependency, the conversion engine. Argument parsing uses Node's own parseArgs. The only optional extras are a headless Chromium for PDF and the Mermaid CLI for diagrams.
How do I convert a whole folder of Markdown files?
Quote a glob and give it a destination directory: md2word "docs/*.md" --out-dir dist/. One file failing does not stop the rest; the failure is reported and the exit code becomes 1.
Why does the PDF command fail on a clean machine?
Because no headless Chromium is installed. Add playwright or puppeteer as a dev dependency, or convert with --to html and print from your browser. The CLI refuses rather than writing an empty PDF.
Can I use it in CI?
That is what the exit codes and --json are for: 2 means the invocation was wrong, 1 means a document failed, 0 means everything converted. Parse the JSON for per-file warnings if your build should fail on a skipped image.
Will it apply my company's Word template?
Yes, with --reference-doc template.docx, which copies the template's style definitions exactly as Pandoc's flag does. The scope and limits of that are documented on Markdown to Word with template.
Is the CLI free, or does it check my plan?
It runs the full engine locally with no entitlement check, so every flag works once installed. The free and Pro split described on the pricing page applies to the hosted service, not to a package on your own machine.