# Convert DOCX to PDF in Node.js

Convert DOCX to PDF in Node.js with JavaScript or TypeScript. Read Word files, write PDF bytes, and handle font and fidelity errors without LibreOffice.

Use the TypeScript library to convert Word (DOCX) files to PDF in a Node.js application without LibreOffice or Microsoft Word. The exporter takes DOCX bytes and returns PDF bytes with a page count, font resolution report, diagnostics, and timings. Conversion does not modify the source document.

## Install the package

Install the converter and its dependencies from npm:

```sh
npm install @docx-editor.dev/docx-to-pdf
```

The [EigenPal Pro License](/guides/getting-started) permits internal, non-production evaluation. Production use requires a commercial agreement.

The package supports Node.js `^20.16.0 || >=22.3.0`. Use a currently supported Node.js release in your deployment.

## Convert DOCX to PDF with JavaScript or TypeScript

```ts
import { readFile, writeFile } from 'node:fs/promises';
import { exportPdf } from '@docx-editor.dev/docx-to-pdf';

const source = await readFile('document.docx');
const result = await exportPdf(source, {
  fidelityPolicy: 'strict',
  displayMode: 'proposed',
  comments: true,
});

await writeFile('document.pdf', result.bytes);
console.log('Pages:', result.pageCount);
console.log('Fonts:', result.fontResolution);
console.log('Diagnostics:', result.diagnostics);
```

The example uses standard JavaScript and also works in TypeScript. With the package available, save it as `convert.mjs` and run `node convert.mjs`.

`result.bytes` is a `Uint8Array`. Each result owns its byte buffer. Use it to write a file, store an object, or return a response from your own application.

## Handle fidelity errors

Strict mode is the default. It rejects known unsupported or approximate output with `PdfFidelityError`.

```ts
import { readFile, writeFile } from 'node:fs/promises';
import { exportPdf, PdfDocumentOpenError, PdfFidelityError } from '@docx-editor.dev/docx-to-pdf';

try {
  const result = await exportPdf(await readFile('document.docx'));
  await writeFile('document.pdf', result.bytes);
} catch (error) {
  if (error instanceof PdfFidelityError) {
    console.error('Review these fidelity problems:', error.diagnostics);
  } else if (error instanceof PdfDocumentOpenError) {
    console.error('Cannot open DOCX:', error.reason, error.detail);
  } else {
    throw error;
  }
  process.exitCode = 1;
}
```

You can explicitly set `fidelityPolicy: 'best-effort'` when your workflow accepts approximate output. Review `result.diagnostics` before distributing the PDF. Do not automatically retry a strict failure in best-effort mode without deciding how your application will surface the difference.

## Configure revisions and comments

| Option           | Default      | Behavior                                                                                            |
| ---------------- | ------------ | --------------------------------------------------------------------------------------------------- |
| `displayMode`    | `'proposed'` | Show proposed revisions. Use `'original'` for original content or `'all-markup'` to show revisions. |
| `comments`       | `true`       | Include native PDF comment annotations. Use `false` to omit them.                                   |
| `fidelityPolicy` | `'strict'`   | Reject known unsupported or approximate output.                                                     |
| `useSystemFonts` | `true`       | Search standard OS font directories. Disable this for controlled deployments.                       |

Comment display depends on the PDF viewer. Cross-page comments create an annotation on each affected page. Editing an annotation in the PDF does not update the DOCX.

## Bound conversion work

Use `timeoutMs`, `maxOutputBytes`, and `signal` to limit conversion work. The default deadline is 60 seconds and the default output limit is 64 MiB.

```ts
const result = await exportPdf(source, {
  timeoutMs: 30_000,
  maxOutputBytes: 16 * 1024 * 1024,
  signal: AbortSignal.timeout(30_000),
});
```

These are application settings, not a guarantee that every conversion can be interrupted immediately. Synchronous font and image operations cannot be canceled mid-call. For a hard deadline or heap boundary, use a worker with a memory limit and terminate it when the deadline expires.

Apply an input-size limit and control concurrency in your application. See the [Next.js DOCX to PDF guide](/guides/nextjs) for deployment considerations and the [package reference](https://github.com/eigenpal/docx-editor/tree/main/packages/docx-to-pdf) for error types.
