EXPORT CONTENT

Convert DOCX to Markdown with images

Extract images from Word documents, preserve displayed dimensions, and deliver Markdown with image files in a ZIP or local folder.

Set images: true to convert DOCX to Markdown with image links and extracted bytes. Each asset includes its path, MIME type, intrinsic dimensions, and occurrences in the document.

Extract images

import { readFile } from 'node:fs/promises';
import { exportMarkdown } from '@docx-editor.dev/docx-to-markdown';

const bytes = await readFile('document.docx');
const result = await exportMarkdown(bytes, { images: true });

console.log(result.markdown);

for (const image of result.media) {
  console.log(image.path, image.pixelWidth, image.pixelHeight);
  console.log(image.occurrences);
}

Identical image bytes share one asset. Each use has its own occurrence, including page, story, displayed size, and alternative text. Use occurrence metadata when the same file appears at different sizes.

Without images, the exporter omits image links and returns an empty media array.

Preserve displayed sizes

Standard Markdown image syntax does not include dimensions. To include each occurrence's displayed width and height, use HTML syntax:

const result = await exportMarkdown(bytes, {
  images: { syntax: 'html' },
});

The generated img tags include width and height in whole CSS pixels. Configure your Markdown renderer to parse sanitized HTML and retain those attributes.

pixelWidth and pixelHeight describe the image file. An occurrence's displayWidthPx and displayHeightPx describe its displayed dimensions. Word can stretch or shrink an image independently of its intrinsic dimensions.

Cropping, rotation, drawing effects, and floating text wrapping are not reproduced.

Save a folder in Node.js

import { writeMarkdownBundle } from '@docx-editor.dev/docx-to-markdown/node';

await writeMarkdownBundle(result, { directory: './output' });

The helper writes:

output/
  document.md
  document.json
  media/

The parent directory must exist. The output directory must be new or empty; existing files are not overwritten. JSON contains metadata without binary image bytes.

Create a ZIP

import { createMarkdownZip } from '@docx-editor.dev/docx-to-markdown';

const zipBytes = await createMarkdownZip(result);

Use zipBytes in a response or browser download. See the browser download example.

Both ZIP and folder output require relative asset URLs. Export with images: true and no custom URL resolver when you need a portable bundle.

Return hosted image URLs

For server delivery, provide images.resolveUrl. Your application uploads the bytes and returns the resulting URL:

import { exportMarkdown, toMarkdownJSON } from '@docx-editor.dev/docx-to-markdown';

// request, storage, and documentId are supplied by your application.
const result = await exportMarkdown(bytes, {
  signal: request.signal,
  images: {
    resolveUrl: (image, { signal }) =>
      storage.upload(`documents/${documentId}/${image.path}`, image.bytes, {
        contentType: image.mimeType,
        signal,
      }),
  },
});

return Response.json(toMarkdownJSON(result));

toMarkdownJSON() removes image bytes from the JSON response. Your application owns upload cleanup, access control, and signed-URL expiration. The converter does not provide storage or a hosted conversion service.

Review limits and warnings

The default extraction limit is 64 MiB of unique image bytes. This is not a limit on total conversion memory. Use images.maxTotalBytes to set a different extraction budget.

Some image bytes can be extracted even when their story, such as a text box, is omitted from Markdown. Inspect result.warnings and occurrence metadata before treating the output as a complete transcription.

Unsupported images, missing resources, and shapes can remain omitted. The converter does not fetch document-linked external images.

Next steps

INSTALL THE PACKAGE

npm install @docx-editor.dev/docx-to-markdown @docx-editor.dev/core