npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

docx-html-replacer

v1.1.0

Published

Open-source rich-text (HTML) placeholder replacement for DOCX templates. Automatically detects HTML vs plain text and converts to native Word formatting.

Downloads

98

Readme

docx-html-replacer

Open-source rich-text (HTML) placeholder replacement for DOCX templates.

Replace <<placeholder>> tags in .docx files with plain text or HTML content that gets automatically converted to native Word formatting (bold, italic, headings, lists, links, and more).

Quick Start

npm install docx-html-replacer
import { replaceInDocx } from 'docx-html-replacer';
import * as fs from 'fs';

const template = fs.readFileSync('template.docx');

const result = await replaceInDocx(template, {
  title: 'Quarterly Report',
  date: '2025-11-04',
  content: '<h1>Summary</h1><ul><li>Revenue up 15%</li><li>Costs down 8%</li></ul>',
});

fs.writeFileSync('output.docx', result);

Your template uses <<placeholder>> syntax — just create a .docx file with tags like <<title>>, <<date>>, <<content>> and the library handles the rest.

Features

  • Automatic HTML detection — values containing HTML tags are converted to native Word (OOXML) formatting; plain text is inserted as-is.
  • Rich formatting support — bold, italic, underline, strikethrough, headings (<h1><h6>), ordered/unordered lists, hyperlinks, tables.
  • Malformed placeholder safety — gracefully handles <<<...>>>, <<<<...>>>>, and mismatched brackets without crashing.
  • Font customization — configurable font family and size (default: Aptos 10pt).
  • Paragraph justification — optional justified alignment for all paragraphs (list items stay left-aligned).
  • Strict mode — optionally throw errors when placeholders have no replacement value.
  • Case-insensitive matching<<Name>> and <<name>> both match the same replacement key.
  • Custom logger — plug in your own logging (Winston, Pino, console, etc.) via the DocxLogger interface.
  • Structured error handling — all errors throw DocxReplacerError with a machine-readable code, human-readable message, and optional details.
  • Input validation — template size limits, replacement value checks, and prototype-pollution protection out of the box.
  • Cross-runtime input — accepts Buffer, Uint8Array, or ArrayBuffer as template input.

API

replaceInDocx(template, replacements, options?)

Replace placeholders in a DOCX template buffer.

| Parameter | Type | Description | | -------------- | ----------------------------- | --------------------------------------------------- | | template | DocxInput | The .docx file as a Buffer, Uint8Array, or ArrayBuffer | | replacements | Record<string, string> | Key-value map of placeholder names to values | | options | ReplaceOptions (optional) | Configuration for font, justification, logger, etc. |

Returns: Promise<Buffer> — the generated .docx file.

Options

interface ReplaceOptions {
  font?: FontOptions | false;  // Font config, or false to skip font styling
  justify?: boolean;           // Justify paragraphs (default: true)
  logger?: DocxLogger;         // Optional logger
  strict?: boolean;            // Throw on unreplaced placeholders (default: false)
}

interface FontOptions {
  fontFamily?: string;  // Default: 'Aptos'
  fontSize?: number;    // In half-points. Default: 20 (10pt)
}

applyFontStylingOnly(template, options?)

Apply font styling to a DOCX buffer without performing any placeholder replacement.

| Parameter | Type | Description | | ---------- | --------------------------------- | -------------------------------------------------------- | | template | DocxInput | The .docx file as a Buffer, Uint8Array, or ArrayBuffer | | options | FontStylingOptions (optional) | Font, justification, logger |

Returns: Promise<Buffer>

isHtmlString(str)

Utility function: returns true if the given string contains HTML tags (tags must start with a letter or /). Plain text with angle brackets (e.g. 5 < 10 > 5) returns false.

Error Handling

All errors thrown by the library are instances of DocxReplacerError, which extends Error with:

  • code — a machine-readable DocxErrorCode string for programmatic handling
  • details — an optional object with extra context (e.g. which key failed)
  • cause — the original error, when wrapping a third-party failure

Error Codes

| Code | When it's thrown | | ------------------------ | ------------------------------------------------------------- | | INVALID_TEMPLATE | Template is not a Buffer/Uint8Array/ArrayBuffer, or is empty | | TEMPLATE_TOO_LARGE | Template exceeds the 100 MB size limit | | CORRUPT_TEMPLATE | File is not a valid ZIP/DOCX or is missing word/document.xml| | INVALID_REPLACEMENT | A replacement key is reserved, value is not a string, or value exceeds 10 MB | | PLACEHOLDER_MISSING | Strict mode: a placeholder in the template has no replacement | | HTML_CONVERSION_FAILED | The HTML content for a placeholder could not be converted | | RENDER_FAILED | The template could not be rendered (e.g. malformed syntax) |

Example

import { replaceInDocx, DocxReplacerError } from 'docx-html-replacer';

try {
  const result = await replaceInDocx(template, replacements);
} catch (err) {
  if (err instanceof DocxReplacerError) {
    console.error(`[${err.code}] ${err.message}`);
    // err.details  — extra context (key, size, etc.)
    // err.cause    — original error, if any
  }
}

Examples

Plain text replacement

const result = await replaceInDocx(template, {
  company_name: 'Acme Corp',
  date: '2025-11-04',
  ref_number: 'REF-12345',
});

Rich HTML replacement

const result = await replaceInDocx(template, {
  summary: `
    <h2>Project Status</h2>
    <p>The project is <b>on track</b> for delivery.</p>
    <ul>
      <li>Phase 1: <i>Complete</i></li>
      <li>Phase 2: In Progress</li>
      <li>Phase 3: Planned</li>
    </ul>
    <p>See <a href="https://example.com/dashboard">dashboard</a> for details.</p>
  `,
});

Custom font and no justification

const result = await replaceInDocx(
  template,
  { title: 'My Report' },
  {
    font: { fontFamily: 'Calibri', fontSize: 24 }, // 12pt
    justify: false,
  }
);

Strict mode

import { replaceInDocx, DocxReplacerError } from 'docx-html-replacer';

try {
  const result = await replaceInDocx(
    template,
    { title: 'Only Title' },
    { strict: true }
  );
} catch (err) {
  if (err instanceof DocxReplacerError && err.code === 'PLACEHOLDER_MISSING') {
    console.error(err.message);
    // 'The placeholder "<<date>>" in your template has no replacement value. ...'
  }
}

Exports

// Functions
export { replaceInDocx, applyFontStylingOnly, isHtmlString };

// Error class
export { DocxReplacerError };

// Types
export type {
  DocxInput,
  DocxErrorCode,
  ReplaceOptions,
  FontStylingOptions,
  FontOptions,
  DocxLogger,
};

Supported HTML Tags

| Tag | Description | | ------------------------ | ------------------------ | | <p> | Paragraphs | | <h1><h6> | Headings | | <b>, <strong> | Bold | | <i>, <em> | Italic | | <u>, <ins> | Underline | | <s>, <del> | Strikethrough | | <ul>, <ol>, <li> | Lists | | <a href="..."> | Hyperlinks | | <table>, <tr>, <td>| Tables | | <br> | Line breaks | | <span> | Inline styling | | <sub>, <sup> | Subscript / Superscript | | <code> | Code (gray highlight) | | <blockquote> | Block quotes |

Known Limitations

  • DOCX only — does not support PPTX or XLSX.
  • Body content only — placeholders in headers, footers, and other document parts are not processed (only word/document.xml).
  • HTML-to-OOXML conversion relies on html-to-docx; some advanced CSS may not convert perfectly.
  • Complex nested tables may have layout differences between browsers and Word.
  • Image support (<img>) is not included in this version.

Third-Party Licenses

This package depends on the following MIT-licensed open-source libraries:

Disclaimer: This package is independent and not affiliated with Docxtemplater or its commercial modules.

License

MIT