Guide · odf-kit

LibreOffice headless alternative for Node.js

odf-kit generates and converts ODF documents entirely in JavaScript — no LibreOffice installation, no subprocess, no startup delay. Works in Node.js, browsers, serverless functions, and Cloudflare Workers.

The problem with LibreOffice headless

LibreOffice headless (libreoffice --headless --convert-to odt) is the traditional solution for server-side ODF generation and conversion. It works, but it has significant costs in production:

Install

$ npm install odf-kit

HTML → ODT (replaces --convert-to odt)

// Before: libreoffice --headless --convert-to odt document.html
// After:
import { htmlToOdt } from "odf-kit";
import { writeFileSync } from "fs";

const bytes = await htmlToOdt(htmlString, {
  pageFormat: "A4",
  metadata: { title: "My Document" },
});
writeFileSync("document.odt", bytes);
// No process spawn, no 500MB install, works on Lambda

DOCX → ODT (replaces --convert-to odt)

// Before: libreoffice --headless --convert-to odt report.docx
// After:
import { docxToOdt } from "odf-kit/docx";
import { readFileSync, writeFileSync } from "fs";

const { bytes, warnings } = await docxToOdt(readFileSync("report.docx"));
writeFileSync("report.odt", bytes);
// Pure ESM, browser-safe, spec-validated against ECMA-376

ODT → HTML (replaces --convert-to html)

// Before: libreoffice --headless --convert-to html document.odt
// After:
import { odtToHtml } from "odf-kit/reader";
import { readFileSync } from "fs";

const html = odtToHtml(readFileSync("document.odt"), { fragment: true });
// Returns clean HTML string, no temp files

Generate ODT from scratch

import { OdtDocument } from "odf-kit";

const doc = new OdtDocument();
doc.setPageLayout({ width: "8.5in", height: "11in" });
doc.addHeading("Quarterly Report", 1);
doc.addTable([["Region", "Revenue"], ["North", "$2.1M"]]);

const bytes = await doc.save();
// Valid .odt, passes OASIS ODF validator

What LibreOffice still does better

odf-kit is not a complete drop-in for every LibreOffice use case. LibreOffice still has advantages for:

Comparison

Capabilityodf-kitLibreOffice headless
Generate ODT from scratch Pure JS Not supported
HTML → ODT Pure JS Subprocess
DOCX → ODT Pure JS, browser-safe Higher fidelity
ODT → HTML Pure JS
ODT → PDFVia Typst CLI Direct
Browser support Full Impossible
Serverless (Lambda, Vercel)
Startup time Milliseconds 2–5 seconds
Installation size ~50KB 300–500MB
Concurrent conversions No stateRequires separate profiles
Legacy formats (.doc, .xls)

Related guides

Replace LibreOffice headless today

One npm install — no server setup, no Docker layers, no startup delay.

$ npm install odf-kit