Why look for a SheetJS alternative?
SheetJS (xlsx) is the most widely used JavaScript spreadsheet library. It supports many formats and is well-maintained. However, several factors lead developers to look for alternatives:
- Licensing — SheetJS Pro features require a paid license. The free Community Edition has restrictions on commercial use for some features.
- ODF focus — If your target format is .ods (OpenDocument Spreadsheet), odf-kit is purpose-built for ODF and produces spec-compliant output validated on every CI run.
- Bundle size — SheetJS includes support for many legacy formats. odf-kit/ods is focused on ODF only, with zero transitive dependencies.
- Government and public sector — Many governments mandate ODF (ISO/IEC 26300). odf-kit targets this use case directly.
Install
Generate ODS spreadsheets
Use OdsDocument from odf-kit to create .ods files from scratch — the equivalent of SheetJS's XLSX.utils.book_new() workflow, but for ODF:
import { OdsDocument } from "odf-kit"; import { writeFileSync } from "fs"; const doc = new OdsDocument(); const sheet = doc.addSheet("Sales"); // Auto-typed cells: number, Date, boolean, string, null sheet.addRow(["Month", "Revenue", "Growth"], { bold: true, backgroundColor: "#DDDDDD" }); sheet.addRow(["January", 12500, 0.08]); sheet.addRow(["February", 14200, 0.136]); sheet.addRow(["Total", { value: "=SUM(B2:B3)", type: "formula" }]); // Number formats sheet.addRow([{ value: 1234.56, type: "currency", numberFormat: "currency:EUR" }]); sheet.addRow([{ value: 0.1234, type: "percentage", numberFormat: "percentage:1" }]); // Merged cells, freeze, column width, tab color sheet.addRow([{ value: "Q1 Summary", type: "string", colSpan: 3, bold: true }]); sheet.setColumnWidth(0, "4cm"); sheet.freezeRows(1); sheet.setTabColor("#4CAF50"); const bytes = await doc.save(); writeFileSync("sales.ods", bytes);
Convert XLSX to ODS
Use xlsxToOds from odf-kit/xlsx to convert .xlsx files to .ods — no SheetJS dependency, no extra install:
import { xlsxToOds } from "odf-kit/xlsx"; import { readFileSync, writeFileSync } from "fs"; const ods = await xlsxToOds(readFileSync("report.xlsx")); writeFileSync("report.ods", ods); // Also works in the browser const ods2 = await xlsxToOds(await file.arrayBuffer());
Preserves: strings, numbers, booleans, dates (Excel serial → Date), formulas (cached result), merged cells (colSpan/rowSpan), freeze panes, multiple sheets. Own XLSX parser — no SheetJS, no transitive dependencies.
Read ODS files
Use readOds from odf-kit/ods-reader to parse .ods files into typed JavaScript values — the equivalent of SheetJS's XLSX.read() + utils.sheet_to_json():
import { readOds, odsToHtml } from "odf-kit/ods-reader"; import { readFileSync } from "fs"; const model = readOds(readFileSync("data.ods")); for (const row of model.sheets[0].rows) { for (const cell of row.cells) { console.log(cell.type, cell.value); // type: "string"|"float"|"boolean"|"date"|"formula"|"empty"|"covered" // value: string|number|boolean|Date|null — never a display string } } // Or convert to an HTML table directly const html = odsToHtml(readFileSync("data.ods"));
Comparison
| Feature | odf-kit | SheetJS Community |
|---|---|---|
| Generate .ods from scratch | ✓ Full support | Partial |
| Convert .xlsx → .ods | ✓ Own parser, zero deps | ✓ |
| Read .ods files | ✓ Typed values | ✓ |
| Merged cells | ✓ colSpan + rowSpan | ✓ |
| Freeze panes | ✓ | ✓ |
| Number formats (currency, %) | ✓ | ✓ |
| Browser support | ✓ Pure ESM | ✓ |
| License | ✓ Apache 2.0 | Apache 2.0 (Community) |
| Transitive dependencies | ✓ Zero | Some |
| ODF validator compliance | ✓ CI-enforced | Not tested against OASIS validator |
| Legacy formats (.xls, .xlsb) | ✗ .xlsx/.xlsm only | ✓ |
| ODT document support | ✓ Full suite | ✗ |
When to use odf-kit vs SheetJS
Use odf-kit when:
- Your target format is .ods (OpenDocument Spreadsheet)
- You need ODF compliance for government or public sector requirements
- You want zero transitive dependencies and Apache 2.0 licensing with no ambiguity
- You also need ODT document generation in the same project
Use SheetJS when:
- You need to read or write legacy formats (.xls, .xlsb, .xlsm with macros)
- You need to write .xlsx output specifically
- You need advanced Excel-specific features (pivot tables, charts, conditional formatting)