Embed HTML into Word Documents with docx.js the Easy Way

Published: (December 12, 2025 at 04:57 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

QuickStart

Install the library from npm:

npm install html-docxjs-compiler docx

The latest version is compatible with docx ^9.5.0.

Basic example

import { transformHtmlToDocx } from 'html-docxjs-compiler';
import { Document, Packer } from 'docx';
import * as fs from 'fs';

async function createDocument() {
  const html = `
    
## My Document

    
This is a paragraph with **bold** and *italic* text.

    

      - First item

      - Second item

    

  `;

  // Transform HTML to DOCX elements
  const elements = await transformHtmlToDocx(html);

  // Create a document with the elements
  const doc = new Document({
    sections: [{ children: elements }],
  });

  // Generate and save the document
  const buffer = await Packer.toBuffer(doc);
  fs.writeFileSync('output.docx', buffer);
}

createDocument();

More detailed example

The following demo shows how to generate lists, apply element styles, and handle various HTML tags.

const { transformHtmlToDocx } = require('../dist/index');
const { Document, Packer } = require('docx');
const { WORD_NUMBERING_CONFIGURATION } = require('./config');
const fs = require('fs');
const path = require('path');

async function runBasicDemo() {
  console.log('Running Basic Demo...\n');

  const html = `
    
## Welcome to HTML-DOCX Compiler

    
This is a **basic demo** showing how to convert HTML to DOCX format.

    
## Features

    
The package supports:

    

      - Headings (H1 through H6)

      - **Bold** and *italic* text

      - Underlined and strikethrough text

      - Superscript2 and subscript2

      - Links like [GitHub](https://github.com)

    

    
## Ordered Lists

    
You can also create numbered lists:

    

      - First item

      - Second item

      - Third item

    

    
## Text Formatting

    
This text is centered.

    
This text is right-aligned.

    
This text is blue.

    
This text has a yellow background.

    
      
You can also use div elements to group content.

      
Multiple paragraphs within a div work perfectly.

    
  `;

  try {
    console.log('Converting HTML to DOCX elements...');
    const docxElements = await transformHtmlToDocx(html);

    const doc = new Document({
      numbering: WORD_NUMBERING_CONFIGURATION,
      sections: [{ children: docxElements }],
    });

    const buffer = await Packer.toBuffer(doc);
    const outputDir = path.join(__dirname, 'output');

    if (!fs.existsSync(outputDir)) {
      fs.mkdirSync(outputDir, { recursive: true });
    }

    const outputPath = path.join(outputDir, 'basic-demo.docx');
    fs.writeFileSync(outputPath, buffer);

    console.log('✅ Success! Document created at:', outputPath);
  } catch (error) {
    console.error('❌ Error:', error.message);
    console.error(error.stack);
  }
}

runBasicDemo();

The generated document looks like this:

Generated document

Multiple HTML blocks in one document

const headerHtml = `
## Invoice #123
`;
const bodyHtml = `
Thank you for your purchase.
`;
const footerHtml = `
This is an automated document.
`;

const header = compileHtmlToComponents(headerHtml);
const body = compileHtmlToComponents(bodyHtml);
const footer = compileHtmlToComponents(footerHtml);

const doc = new Document({
  sections: [
    {
      children: [
        ...header,
        ...body,
        ...footer,
      ],
    },
  ],
});

Adding images with ease

Even image insertion is straightforward with the library.

const {
  transformHtmlToDocx,
  HttpImageDownloadStrategy,
  ImageDownloadStrategyManager,
} = require('../dist/index');
const { Document, Packer } = require('docx');
const fs = require('fs');
const path = require('path');

async function runAdvancedDemo() {
  console.log('Running Advanced Demo...\n');

  const html = `
    
## Image adding

    
      
**Image example:**

      ![Modern art](https://fastly.picsum.photos/id/237/200/300.jpg?hmac=TmmQSbShHz9CdQm0NkEjx1Dyh_Y984R9LpNrpvH2D_U)
    

    
## Important Notes

    
      ⚠️ **Confidential:** This document contains sensitive information 
      and should not be distributed outside the organization.
    
  `;

  try {
    console.log('Setting up configuration...');
    const strategyManager = new ImageDownloadStrategyManager();
    strategyManager.addStrategy(new HttpImageDownloadStrategy());

    const config = { strategyManager };

    console.log('Converting HTML to DOCX elements...');
    const docxElements = await transformHtmlToDocx(html, config);

    const doc = new Document({
      sections: [
        {
          properties: {
            page: {
              margin: {
                top: 1440,    // 1 inch = 1440 twips
                right: 1440,
                bottom: 1440,
                left: 1440,
              },
            },
          },
          children: docxElements,
        },
      ],
      creator: 'HTML-DOCX Compiler',
    });

    const buffer = await Packer.toBuffer(doc);
    const outputPath = path.join(__dirname, 'advanced-demo.docx');
    fs.writeFileSync(outputPath, buffer);
    console.log('✅ Document with images created at:', outputPath);
  } catch (error) {
    console.error('❌ Error:', error);
  }
}

runAdvancedDemo();
Back to Blog

Related posts

Read more »

Preferred Web Tech Stacks in Australia

Why Tech Stack Selection Matters in Australia Australian businesses prioritize quality, security, and performance. Websites are expected to work seamlessly acr...