
Company News
Free Business Plan Upgrades for Open Source Maintainers
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.
word-to-markdown
Advanced tools
Convert Word documents to beautiful Markdown. Via command line, as a Node library, or in your browser. An even better version of the original word-to-markdown.
Try it in your browser at word2md.com, or use it from the command line — no clone required:
npx word-to-markdown input.docx > output.md
<sup>/<sub> tags1./2./3. by default)1./2./3. ordered lists. Pass
{ numberedLists: 'bullets' } (library) or --bullet-lists (CLI) to convert
them to bullet lists instead (matching the original word-to-markdown).{ images: 'extract' } (library — the
bytes come back on ConvertResult.images) or --image-dir <dir> (CLI). Drop
them entirely with { images: 'strip' } / --strip-images. On the web,
documents with images offer a Download .zip (Markdown + an images/
folder). For full control, pass a custom Mammoth image handler
via options.mammoth.{ underline: 'preserve' } (library) or
--underline (CLI) to keep it as an inline <u> tag..docx → HTML step. When content is dropped this way,
convertWithWarnings surfaces a warning.TL;DR: This project is a complete rewrite, using modern tools and libraries, and is much faster and more reliable. The output should be the same or better. Feedback welcome!
Word to Markdown is designed with privacy as a core principle. The application operates entirely client-side:
Whether you use the command line tool, run it locally in your browser, or use the hosted version, your documents and privacy are protected.
Run it directly with npx (downloads and runs the latest published version):
npx word-to-markdown path/to/your/file.docx > output.md
Or install it globally to get the w2m command:
npm install -g word-to-markdown
w2m path/to/your/file.docx > output.md
The converted Markdown is written to stdout and any document warnings (encryption, sensitivity labels, and the like) to stderr, so a redirect captures only the Markdown. The command exits with a non-zero status and a friendly message if the file is missing, unreadable, or not a valid .docx. Only .docx is supported — re-save older .doc files as .docx first.
Options:
--bullet-lists — convert numbered lists to bullets instead of keeping 1./2./3..--underline — preserve underlined text as inline <u> tags (dropped by default).--strip-images — remove images instead of embedding them as base64 data URIs.--image-dir <dir> — extract images to <dir> and link them relatively, instead
of embedding base64. Links resolve relative to where you save the Markdown, e.g.
w2m --image-dir images report.docx > report.md.Published to npm as word-to-markdown. It ships as an ES module and requires Node 22.13 or later.
npm install word-to-markdown
import convert, { convertWithWarnings } from 'word-to-markdown';
// Just the Markdown:
const markdown = await convert('path/to/your/file.docx');
// Markdown plus any document warnings (e.g. encryption, sensitivity labels):
const { markdown, warnings } = await convertWithWarnings(
'path/to/your/file.docx',
);
Both functions accept either a file-path string (in Node) or an ArrayBuffer (in the browser), so the same code runs in either environment:
const { markdown } = await convertWithWarnings(arrayBuffer);
convert(input, options?): Promise<string> — resolves to the Markdown.convertWithWarnings(input, options?): Promise<{ markdown: string; warnings: string[]; images? }> — also returns human-readable warnings for encrypted, protected, or sensitivity-labeled documents, and (in extract mode) the extracted images.input is a file-path string (Node) or an ArrayBuffer (browser). options is optional:
images — 'inline' (default) embeds images as base64 data URIs; 'strip' removes them; 'extract' replaces each with a relative  link and returns the bytes on ConvertResult.images (use convertWithWarnings to retrieve them).imageDir — link/path prefix for extracted images (default 'images'); only applies with images: 'extract'.numberedLists — 'ordered' (default) keeps 1./2./3.; 'bullets' converts numbered lists to bullets.underline — 'ignore' (default) drops underlines; 'preserve' keeps them as inline <u> tags.mammoth / turndown — escape hatches forwarded to Mammoth and Turndown respectively.// Extract images to files and write them out yourself:
const { markdown, images } = await convertWithWarnings('file.docx', {
images: 'extract',
});
// markdown → ; images → [{ path, contentType, bytes }]
Conversion throws typed errors so you can respond to each failure precisely:
import convert, {
UnsupportedFileError,
FileNotFoundError,
InvalidFileError,
FilePermissionError,
ConversionError,
} from 'word-to-markdown';
try {
const markdown = await convert('path/to/your/file.docx');
} catch (error) {
if (error instanceof UnsupportedFileError) {
// e.g. a .doc file — only .docx is supported
} else if (error instanceof FileNotFoundError) {
// the path doesn't exist
} else if (error instanceof InvalidFileError) {
// not a valid or parseable .docx
} else if (error instanceof FilePermissionError) {
// the file couldn't be read
} else if (error instanceof ConversionError) {
// something failed mid-conversion — see error.cause
}
}
npm installRun npm run build:js once, then node build/cli.js path/to/your/file.docx.
npm run dev starts the Astro dev server. To preview a production build, run
npm run build followed by npm run preview.
To self-host the static site using Docker Compose:
npm install && npm run builddocker compose up -dSee the README of the original Word to Markdown for the project's motivation.
The Original Word to Markdown is 10 years old. The conversion process was as follows:
Not only did this process require installing and shelling out to a huge binary (LibreOffice), but it was very fragile, and key projects like Reverse Markdown are no longer maintained. I tried experimenting with Pandoc, but it had many of the same limitations.
All three of these projects are actively maintained and heavily used, and allows us to convert the document faster, and entirely in JavaScript. Heck, I think theoretically, this could run in the browser for added privacy.
It's still young, but so far, I've found the output to be better, with much less manual cleanup required. Notice something is off? Please open an issue.
One note: This project does not yet attempt to guess heading levels based on font size. It could, but it's not yet implemented.
FAQs
Convert Word documents to beautiful Markdown.
The npm package word-to-markdown receives a total of 59 weekly downloads. As such, word-to-markdown popularity was classified as not popular.
We found that word-to-markdown demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.