JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 9000
  • Score
    100M100P100Q145001F
  • License MPL-2.0

LibreOffice WASM document conversion toolkit - headless document format conversion

Package Exports

  • @matbee/libreoffice-converter
  • @matbee/libreoffice-converter/browser
  • @matbee/libreoffice-converter/package.json
  • @matbee/libreoffice-converter/server
  • @matbee/libreoffice-converter/types
  • @matbee/libreoffice-converter/wasm/loader

Readme

LibreOffice WASM Document Converter

Convert documents between formats (DOCX, PDF, XLSX, PPTX, etc.) in Node.js or browsers using LibreOffice compiled to WebAssembly. No native dependencies required.

Features

  • Pure WebAssembly - No native LibreOffice installation required
  • Wide Format Support - Convert between 15+ document formats
  • Cross-Platform - Works in Node.js and browsers
  • Fast - ~35ms per conversion after initialization

Installation

npm install @matbee/libreoffice-converter

Demo

https://convertmydocuments.com

Quick Start

One-Shot Conversion (Simplest)

import { convertDocument } from '@matbee/libreoffice-converter';
import fs from 'fs';

const docx = fs.readFileSync('document.docx');
const result = await convertDocument(docx, { outputFormat: 'pdf' });
fs.writeFileSync('document.pdf', result.data);

Export as Image

import { exportAsImage } from '@matbee/libreoffice-converter';
import fs from 'fs';

// Export single page (0-indexed)
const [cover] = await exportAsImage(docxBuffer, 0, 'png');
fs.writeFileSync('cover.png', cover.data);

// Export multiple pages
const slides = await exportAsImage(pptxBuffer, [0, 1, 2], 'png');
slides.forEach((img, i) => fs.writeFileSync(`slide-${i}.png`, img.data));

// Export with options
const highRes = await exportAsImage(pptxBuffer, [0, 1, 2], 'png', { dpi: 300, width: 1920 });

For servers, use the worker converter to avoid blocking the main thread:

import { createWorkerConverter } from '@matbee/libreoffice-converter/server';

const converter = await createWorkerConverter();

// Reuse for multiple conversions
const pdf = await converter.convert(docxBuffer, { outputFormat: 'pdf' });
const csv = await converter.convert(xlsxBuffer, { outputFormat: 'csv' });

await converter.destroy(); // Clean up when done

Supported Formats

Input: doc, docx, xls, xlsx, ppt, pptx, odt, ods, odp, rtf, txt, html, csv, pdf, epub

Output: pdf, docx, doc, odt, rtf, txt, html, xlsx, xls, ods, csv, pptx, ppt, odp, png, jpg, svg

Browser Usage

import { WorkerBrowserConverter, createWasmPaths } from '@matbee/libreoffice-converter/browser';

const converter = new WorkerBrowserConverter({
  ...createWasmPaths('/wasm/'),
  browserWorkerJs: '/dist/browser.worker.js',
  onProgress: (info) => console.log(`${info.percent}%: ${info.message}`),
});

await converter.initialize();

const result = await converter.convert(fileData, { outputFormat: 'pdf' }, 'doc.docx');

// Download result
const blob = new Blob([result.data], { type: result.mimeType });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = result.filename;
a.click();

Required HTTP headers for SharedArrayBuffer:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

Font Support

The WASM build includes Latin, Arabic, Hebrew, and other common fonts. For CJK (Chinese, Japanese, Korean), Indic, and other scripts, you can inject additional fonts at runtime.

Using System Fonts (Node.js)

const converter = await createSubprocessConverter({ includeSystemFonts: true });

Using @fontsource Packages

Install fonts from npm, then load them:

npm install @fontsource/noto-sans-jp @fontsource/noto-sans-kr
import { loadFontsFromPackages, createSubprocessConverter } from '@matbee/libreoffice-converter';

const fonts = await loadFontsFromPackages([
  '@fontsource/noto-sans-jp',
  '@fontsource/noto-sans-kr',
]);
const converter = await createSubprocessConverter({ fonts });

Using Prebuilt Font Bundles

Download regional font bundles from GitHub Releases:

Bundle Scripts Size
fonts-core.zip Latin, Cyrillic, Greek ~6 MB
fonts-cjk.zip Chinese, Japanese, Korean ~250 MB
fonts-arabic.zip Arabic, Hebrew ~1.3 MB
fonts-indic.zip Devanagari, Bengali, Tamil, Telugu, etc. ~4.5 MB
fonts-southeast-asian.zip Thai, Myanmar, Khmer, Lao ~1.4 MB
fonts-african.zip Ethiopic ~835 KB
fonts-all.zip All of the above ~264 MB
import { loadFontsFromZip, createSubprocessConverter } from '@matbee/libreoffice-converter';

const fonts = await loadFontsFromZip('./fonts/fonts-cjk.zip');
const converter = await createSubprocessConverter({ fonts });

Custom Font Files

import { loadFontsFromDirectory, createSubprocessConverter } from '@matbee/libreoffice-converter';

const fonts = await loadFontsFromDirectory('./my-fonts/');
const converter = await createSubprocessConverter({ fonts });

Browser Font Loading

import { loadFontsFromUrl, WorkerBrowserConverter } from '@matbee/libreoffice-converter/browser';

const fonts = await loadFontsFromUrl('/assets/fonts-cjk.zip');
const converter = new WorkerBrowserConverter({ ...wasmPaths, fonts });
await converter.initialize();

Documentation

  • API Reference - Complete API documentation, types, configuration options
  • Examples - Express server, React component, batch conversion, and more

System Requirements

  • Node.js 18.0.0+
  • ~150MB disk space for WASM files
  • Browser: ~240MB initial download (cached after first load)

License

MPL-2.0 (same as LibreOffice)

Contributing

Ensure you have git LFS and pnpm installed.

git clone https://github.com/matbeedotcom/libreoffice-document-converter.git
cd libreoffice-document-converter
pnpm install
pnpm build
pnpm test

See docs/API.md#building-from-source for building the WASM module.