# How to Use html-to-pdfmake in Node.js vs Browser: Complete Guide

> Learn how to use html-to-pdfmake in Node.js vs browser. Understand the key differences and achieve effortless PDF generation for your Node.js applications.

- Repository: [Aymeric/html-to-pdfmake](https://github.com/aymkdn/html-to-pdfmake)
- Tags: how-to-guide
- Published: 2026-02-26

---

**To use html-to-pdfmake in Node.js, you must supply a jsdom `window` object via the `window` option, while the browser build automatically uses the native global `window` without extra configuration.**

`html-to-pdfmake` is a lightweight wrapper that converts HTML strings into PDFMake document-definition objects. Whether you are generating PDFs server-side with Node.js or client-side in a web application, the library shares the same core conversion logic found in [`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js). The only difference lies in how the DOM parsing environment is provided.

## How html-to-pdfmake Works Across Environments

The library abstracts DOM parsing through a `window` reference. In the browser, this is the native global object. In Node.js, you must create this context using jsdom.

### Node.js Implementation with jsdom

When running in Node.js, `html-to-pdfmake` relies on the `window` option to access `DOMParser`. According to the source code in [`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js) (lines 21-24), the constructor uses `new this.wndw.DOMParser()` to parse the HTML string. Without supplying a jsdom window, this call fails because Node.js lacks a native DOM.

The constructor (lines 41-48) stores the provided window, initializes default styles, and creates a random suffix for image references. This setup allows the recursive `parseElement` function to traverse the DOM tree exactly as it would in a browser.

### Browser Implementation

In the browser, the library uses the pre-bundled [`browser.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/browser.js) file, which exposes a global `htmlToPdfmake` function. This build automatically references the browser's native `window` and `DOMParser`, eliminating the need for jsdom or any manual window injection.

The same `parseElement` logic handles text nodes, element nodes, tables, lists, and images. Style resolution via `applyStyle` merges default CSS, inline styles, and class names regardless of the environment.

## Complete Node.js Setup Example

To use `html-to-pdfmake` server-side, install the required dependencies and provide a jsdom window:

```javascript
// npm install html-to-pdfmake jsdom pdfmake

const pdfMake = require('pdfmake/build/pdfmake');
const pdfFonts = require('pdfmake/build/vfs_fonts');
pdfMake.vfs = pdfFonts; // Required for fonts

const { JSDOM } = require('jsdom');
const htmlToPdfmake = require('html-to-pdfmake');

// Create a jsdom window for DOM parsing
const { window } = new JSDOM('');

const html = `
  <h1>Server-Side PDF</h1>
  <p>This <strong>bold</strong> text renders via Node.js.</p>
`;

const docDefinition = {
  content: htmlToPdfmake(html, { window }) // Pass the window option
};

pdfMake.createPdf(docDefinition).getBuffer((buffer) => {
  require('fs').writeFileSync('output.pdf', buffer);
});

```

**Critical requirements for Node.js:**

- The `window` option is mandatory and must be a jsdom window object.
- `pdfmake` requires virtual font files (`vfs`) to render text.

## Complete Browser Setup Example

For client-side usage, include the bundled script and use the global function:

```html
<!DOCTYPE html>
<html>
<head>
  <!-- pdfmake core and fonts -->
  <script src="https://cdn.jsdelivr.net/npm/pdfmake@latest/build/pdfmake.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/pdfmake@latest/build/vfs_fonts.min.js"></script>
  
  <!-- html-to-pdfmake browser build -->
  <script src="https://cdn.jsdelivr.net/npm/html-to-pdfmake/browser.js"></script>
</head>
<body>
  <script>
    const html = `
      <h1>Client-Side PDF</h1>
      <p>An <em>italic</em> paragraph with an image:</p>
      <img src="https://example.com/logo.png" width="100">
    `;

    // No window argument needed; uses native browser DOM
    const content = htmlToPdfmake(html);
    
    pdfMake.createPdf({ content }).download('browser-output.pdf');
  </script>
</body>
</html>

```

**Key differences from Node.js:**

- No `jsdom` installation or `window` option required.
- The [`browser.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/browser.js) bundle exposes `htmlToPdfmake` as a global function.
- Image handling can use `imagesByReference` for advanced use cases.

## Key Configuration Options

Both environments accept the same options object passed to `htmlToPdfmake(html, options)`:

- **`window`** – **Required in Node.js.** A jsdom window object providing `DOMParser`. In the browser, this is ignored in favor of the global `window`.
- **`defaultStyles`** – Override default element styling (e.g., `h1: { fontSize: 30, bold: true }`).
- **`tableAutoSize`** – Boolean to enable automatic table sizing based on CSS `width`/`height` attributes and `<colgroup>` definitions.
- **`imagesByReference`** – Boolean (browser only). When `true`, images are returned as reference keys rather than embedded data URIs, producing a separate `images` object in the result.
- **`removeTagClasses`** – Boolean to disable automatic generation of `html-TAG` classes (e.g., `html-div`, `html-p`).
- **`customTag`** – Function callback to intercept specific HTML tags and return custom PDFMake content structures.

## Core Source Files and Architecture

The library maintains a single code path for both environments through these key files:

- **[`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js)** – The core implementation containing the `htmlToPdfMake` class constructor (lines 41-48), DOM parsing logic (lines 21-24), and the recursive `parseElement` method. This file handles style aggregation via `applyStyle` and special element processing for tables, images, and lists.
- **[`browser.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/browser.js)** – A UMD bundle that wraps the core logic for browser usage, exposing the global `htmlToPdfmake` function without requiring module loaders.

Both builds export the same `htmlToPdfmake` function that instantiates the internal class. The constructor stores the provided `window` reference (critical for Node.js), initializes default styles, and prepares image reference tracking. The `parseElement` method then walks the DOM tree depth-first, using `searchForStack` to determine whether content should render as a PDFMake stack or text node.

## Summary

- **html-to-pdfmake** converts HTML strings into PDFMake document definitions using a shared core in [`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js).
- **Node.js usage** requires installing `jsdom` and passing the resulting `window` object via the `window` option.
- **Browser usage** loads the pre-bundled [`browser.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/browser.js) and uses the native global `window` automatically.
- Both environments support identical options including `defaultStyles`, `tableAutoSize`, and `customTag` callbacks.
- The library handles complex elements like tables, images, and nested lists through recursive DOM parsing and style aggregation.

## Frequently Asked Questions

### Do I need jsdom to use html-to-pdfmake in Node.js?

Yes. The library requires a DOM environment to parse HTML strings. In Node.js, you must install `jsdom` and pass the resulting window object via the `window` option: `htmlToPdfmake(html, { window: new JSDOM('').window })`. Without this, the library cannot access `DOMParser` and will throw an error.

### Can I use html-to-pdfmake in the browser without a bundler?

Yes. The library ships a pre-bundled [`browser.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/browser.js) file that you can load via CDN or script tag. This exposes a global `htmlToPdfmake` function that automatically uses the browser's native `window` and `DOMParser`. No module bundler or jsdom is required for browser usage.

### What is the difference between the [`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js) and [`browser.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/browser.js) builds?

[`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js) is the core CommonJS module designed for Node.js environments where you must manually provide a `window` object (typically via jsdom). [`browser.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/browser.js) is a UMD bundle that wraps the same core logic but assumes a global browser `window` is available. Both expose the same `htmlToPdfmake` function and support identical configuration options.

### Does html-to-pdfmake support images in both Node.js and the browser?

Yes, but with different considerations. In both environments, the library can process `<img>` tags with `src` attributes. In the browser, you can set `imagesByReference: true` to return image references separately from the content definition, which is useful for managing binary image data. In Node.js, ensure your jsdom window can resolve image URLs or use data URIs for embedded images.