LibreOffice · WebAssembly · CDN

LibreOffice WASM assets

A cross-origin host for the @matbee/libreoffice-converter browser runtime. Every file is served with Access-Control-Allow-Origin: *, so you can load the ~235 MB LibreOffice WebAssembly runtime from another origin and convert documents entirely in the browser.

version …

Try it

Drop a document here, or click to choose .odt, .docx, .xlsx, .pptx, .rtf … → PDF, in your browser

First run downloads the LibreOffice WASM runtime (~235 MB) and can take a minute; it is then cached by the browser. Everything runs locally — files never leave your device.

What is this?

The npm package ships the LibreOffice WASM binaries (soffice.wasm ≈ 140 MB, soffice.data ≈ 95 MB), which are too large for public npm CDNs and can't be committed into most projects. This page mirrors that browser runtime on GitHub Pages so it can be fetched cross-origin — and runs the demo above from the very same files.

Quick start

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

// A Worker script can't be loaded cross-origin, so keep the small JS glue
// (dist/ + soffice.js + soffice.worker.js) same-origin and load only the
// two heavy binaries from this CDN.
const CDN = '__ORIGIN__';

const converter = new WorkerBrowserConverter({
  ...createWasmPaths('/wasm/'),               // soffice.js + soffice.worker.js: same-origin
  sofficeWasm: `${CDN}/wasm/soffice.wasm`,     // ≈140 MB from the CDN
  sofficeData: `${CDN}/wasm/soffice.data`,     // ≈95 MB from the CDN
});

await converter.initialize();
const { data } = await converter.convert(fileBytes, { outputFormat: 'pdf' }, 'doc.docx');

Files

Requirements

Cross-origin isolation. The converter uses SharedArrayBuffer, so the page that runs it must be served with Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp (or credentialless). GitHub Pages can't set these, so this page uses a service worker to enable isolation client-side; in your own app, set the headers on the server.