docx, html-docx-js, and mammoth are essential tools for handling Microsoft Word documents in JavaScript environments, but they serve distinct directions in the data flow. docx is a modern library designed for programmatically creating .docx files from scratch using JavaScript objects. html-docx-js focuses on converting HTML content directly into Word format, acting as a bridge between web views and documents. mammoth takes the opposite approach, specializing in converting existing .docx files into HTML or plain text for display in web applications. Together, they cover the full lifecycle of document handling — creation, HTML-to-Word conversion, and Word-to-HTML extraction.
When working with Microsoft Word files in JavaScript, developers often face confusion about which library handles which part of the pipeline. docx, html-docx-js, and mammoth are not direct competitors — they are specialized tools for different directions of data flow. Understanding their specific roles is critical for architectural decisions.
The most important distinction is the direction of conversion. docx builds files from JavaScript objects. html-docx-js wraps HTML into a Word file. mammoth unwraps Word files into HTML.
docx creates documents from scratch using a structured API.
// docx: Creating a document from JS objects
const { Document, Packer, Paragraph } = require("docx");
const doc = new Document({
sections: [{
properties: {},
children: [
new Paragraph({ text: "Hello World" })
]
}]
});
Packer.toBuffer(doc).then(buffer => {
// Save buffer to file
});
html-docx-js converts an HTML string directly into a buffer.
// html-docx-js: Converting HTML to Docx
const htmlDocx = require('html-docx-js');
const fs = require('fs');
const htmlContent = '<h1>Hello World</h1>';
const converted = htmlDocx.asBuffer(htmlContent);
fs.writeFileSync('document.docx', converted);
mammoth extracts HTML from an existing .docx file.
// mammoth: Converting Docx to HTML
const mammoth = require("mammoth");
mammoth.convertToHtml({ path: "document.docx" })
.then(result => {
const html = result.value; // The generated HTML
console.log(html);
});
How you control the look of the document varies wildly between these tools. docx requires defining styles in JavaScript. html-docx-js relies on inline CSS. mammoth uses a style map to translate Word styles to HTML.
docx uses a dedicated styling system within the library.
// docx: Defining styles programmatically
const { HeadingLevel } = require("docx");
const doc = new Document({
sections: [{
children: [
new Paragraph({
text: "Title",
heading: HeadingLevel.HEADING_1
})
]
}]
});
html-docx-js uses standard HTML CSS for styling.
// html-docx-js: Styling via CSS
const html = `
<h1 style="color: blue; font-size: 20px;">Title</h1>
<p style="font-family: Arial;">Content</p>
`;
const converted = htmlDocx.asBuffer(html);
mammoth maps Word styles to HTML classes or tags.
// mammoth: Custom style mapping
const options = {
styleMap: [
"p[style-name='Heading 1'] => h1:fresh",
"p[style-name='Normal'] => p"
]
};
mammoth.convertToHtml({ path: "input.docx" }, options);
Images are a common requirement. Each library handles image data differently based on its input source.
docx requires image buffers or data URIs defined in the object tree.
// docx: Adding images from buffer
const { ImageRun } = require("docx");
const fs = require("fs");
const imageBuffer = fs.readFileSync("image.png");
const doc = new Document({
sections: [{
children: [
new Paragraph({
children: [
new ImageRun({
data: imageBuffer,
transformation: { width: 100, height: 100 }
})
]
})
]
}]
});
html-docx-js supports standard HTML image tags with Base64 sources.
// html-docx-js: Images via HTML tags
const html = `
<img src="data:image/png;base64,iVBORw0KGgo..." />
`;
const converted = htmlDocx.asBuffer(html);
mammoth extracts images and can return them as separate files or Base64.
// mammoth: Extracting images
const options = {
convertImage: mammoth.images.imgElement(function(image) {
return image.read("base64").then(function(imageBuffer) {
return {
src: "data:" + image.contentType + ";base64," + imageBuffer
};
});
})
};
mammoth.convertToHtml({ path: "input.docx" }, options);
When selecting a library for long-term projects, maintenance status is a key factor. docx and mammoth are actively maintained with regular updates. html-docx-js has seen less activity in recent years.
docx is the current industry standard for generation.
mammoth is stable and reliable for extraction.
html-docx-js is considered legacy by many architects.
docx for better control, or use forks like html-docx-js-typescript.| Feature | docx | html-docx-js | mammoth |
|---|---|---|---|
| Primary Goal | Create .docx from JS | Convert HTML to .docx | Convert .docx to HTML |
| Input Format | JavaScript Objects | HTML String | .docx File |
| Output Format | .docx Buffer | .docx Buffer | HTML String |
| Styling | JS Object API | CSS | Style Mapping |
| Image Support | Buffers / URIs | Base64 / URLs | Extraction to Base64 |
| Maintenance | ✅ Active | ⚠️ Low Activity | ✅ Active |
These libraries are best viewed as parts of a complete document system rather than alternatives to each other.
docx is your authoring engine. Use it when you own the data and need to build a document dynamically. It gives you the most power but requires the most code.
html-docx-js is your quick exporter. Use it when you have a web view and need to let users download it as a Word file. It is fast to implement but less robust.
mammoth is your importer. Use it when users upload Word files and you need to display or process that content on the web. It ensures clean HTML output without legacy Word markup.
Final Thought: For modern applications, a common pattern is using mammoth to import legacy content, storing it as HTML in your database, and using docx to regenerate professional reports from that data when needed. Avoid relying solely on html-docx-js for critical document generation if you require strict formatting control.
Choose html-docx-js if your content already exists as HTML and you need a quick conversion to Word format without rebuilding the layout in JavaScript objects. It is suitable for features like 'Export to Word' buttons on web pages where the visual fidelity of the HTML is the priority. Note that this package is older and may lack support for newer Word features compared to docx.
Choose docx when you need to generate complex Word documents programmatically from data sources like databases or APIs. It offers the most control over document structure, styles, and elements like tables or charts. This is the best fit for reporting engines, invoice generators, or any scenario where the document structure is defined in code rather than existing templates.
Choose mammoth when you need to import or display content from existing Word documents within a web application. It is ideal for content management systems, document viewers, or migration tools where the goal is to extract clean HTML from .docx files. It does not create documents, so it is not suitable for generation tasks.
This is a very small library that is capable of converting HTML documents to DOCX format that is used by Microsoft Word 2007 and onward. It manages to perform the conversion in the browser by using a feature called 'altchunks'. In a nutshell, it allows embedding content in a different markup language. We are using MHT document to ship the embedded content to Word as it allows to handle images. After Word opens such file, it converts the external content to Word Processing ML (this is how the markup language of DOCX files is called) and replaces the reference.
Altchunks were not supported by Microsoft Word for Mac 2008 and are not supported by LibreOffice and Google Docs.
This library should work on any modern browser that supports Blobs (either natively or via
Blob.js). It was tested on Google Chrome 36, Safari 7 and
Internet Explorer 10.
It also works on Node.js (tested on v0.10.12) using Buffer instead of Blob.
This library supports only inlined base64 images (sourced via DATA URI). But it is easy to convert a
regular image (sourced from static folder) on the fly. If you need an example of such conversion you can checkout a demo page source (see function convertImagesToBase64).
Very minimal demo is available as test/sample.html in the repository and
online. Please note that saving
files on Safari is a little bit convoluted and the only reliable method seems to be falling back
to a Flash-based approach (such as Downloadify).
Our demo does not include this workaround to keep things simple, so it will not work on Safari at
this point of time.
You can also find a sample for using it in Node.js environment here.
To generate DOCX, simply pass a HTML document (as string) to asBlob method to receive Blob (or Buffer)
containing the output file.
var converted = htmlDocx.asBlob(content);
saveAs(converted, 'test.docx');
asBlob can take additional options for controlling page setup for the document:
orientation: landscape or portrait (default)margins: map of margin sizes (expressed in twentieths of point, see
WordprocessingML documentation for details):
top: number (default: 1440, i.e. 2.54 cm)right: number (default: 1440)bottom: number (default: 1440)left: number (default: 1440)header: number (default: 720)footer: number (default: 720)gutter: number (default: 0)For example:
var converted = htmlDocx.asBlob(content, {orientation: 'landscape', margins: {top: 720}});
saveAs(converted, 'test.docx');
IMPORTANT: please pass a complete, valid HTML (including DOCTYPE, html and body tags).
This may be less convenient, but gives you possibility of including CSS rules in style tags.
html-docx-js is distributed as 'standalone' Browserify module (UMD). You can require it as
html-docx. If no module loader is available, it will register itself as window.htmlDocx.
See test/sample.html for details.
Copyright (c) 2015 Evidence Prime, Inc. See the LICENSE file for license rights and limitations (MIT).