xlsx-format
v2.4.5
Published
Modern XLSX reader/writer for TypeScript, Node.js, and browsers. Zero dependencies, async APIs, styled report exports.
Maintainers
Readme
xlsx-format
The XLSX library your bundler will thank you for. Zero dependencies. Promise-based read and write APIs. Works in Node.js and the browser. Use it for simple data conversion, or replace ExcelJS for styled browser report exports without carrying a workbook framework just for formatting.
npm install xlsx-formatimport { readFile, writeFile } from "node:fs/promises";
import { read, write, sheetToJson, jsonToSheet, createWorkbook } from "xlsx-format";
// Read an Excel file into JSON
const workbook = await read(await readFile("report.xlsx"));
const rows = sheetToJson(workbook.Sheets[workbook.SheetNames[0]]);
// Write JSON back to Excel
const sheet = jsonToSheet([
{ Name: "Alice", Revenue: 48000 },
{ Name: "Bob", Revenue: 52000 },
]);
await writeFile("output.xlsx", await write(createWorkbook(sheet, "Q4 Sales")));Why xlsx-format?
Most projects just need XLSX. A focused library keeps the bundle and workbook API small while leaving file-system I/O to the host application.
xlsx-format does one thing well: read and write modern Excel files. The result is a library you can actually tree-shake, await, and ship to the browser without a separate bundle.
| | xlsx-format 2.4.2 | SheetJS 0.18.12 | ExcelJS 4.4.0 |
| ------------------- | ------------------------------ | ------------------------ | -------------------------------- |
| Written in | TypeScript (strict) | JavaScript with typings | JavaScript with TypeScript types |
| Async | Promise-based API | Synchronous public API | Promise-based selected APIs |
| Module format | ESM + CJS | ESM + CJS | CJS + browser build |
| Tree-shakeable | Yes | Limited | Limited |
| Browser support | Yes (read / write) | Yes (separate bundle) | Yes (exceljs.browser.js) |
| Formats | XLSX / XLSM / CSV / TSV / HTML | Many spreadsheet formats | XLSX / CSV |
| Styled reports | Yes | Yes | Yes |
| API style | Named exports | Namespace object | Class-based |
| License | Apache 2.0 | Apache 2.0 | MIT |
The version labels identify the snapshots used for this orientation table. The SheetJS package metadata advertises ESM/CJS entry points and browser bundles. ExcelJS documents its browser build and workbook API in its browser documentation.
For a detailed feature matrix (cell data, formulas, styles, comments, hyperlinks, and more), see Why xlsx-format? in the docs.
XLSM support covers workbook cell data and macro-free output containers. VBA projects are not read, preserved, or written, so do not use an XLSM read/write round trip when macros must survive unchanged.
Runs everywhere
xlsx-format is fully platform-agnostic -- it never imports node:fs or any other Node.js built-in. This means it works out of the box in browsers, edge runtimes (Cloudflare Workers, Deno Deploy), and Node.js without bundler polyfills.
Node.js -- Pair read() / write() with Node's fs module:
import { readFile, writeFile } from "node:fs/promises";
import { read, write } from "xlsx-format";
const wb = await read(await readFile("input.xlsx"));
await writeFile("output.xlsx", await write(wb));Browsers -- Use the File API or fetch:
import { read, write } from "xlsx-format";
// Read from a file input
const wb = await read(await file.arrayBuffer());
// Trigger a download
const blob = new Blob([await write(wb, { type: "array" })], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
});
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "output.xlsx";
link.click();Security
For vulnerability reports and supported versions, see the Security Policy. The Security Considerations guide covers untrusted uploads, export safety, and recommended deployment patterns.
When exporting user-controlled data, the built-in guards for spreadsheet formulas and unsafe HTML links are enabled by default. Keep those defaults for untrusted data; set the options to false only when you need exact text or link fidelity and control the output destination:
import { sheetToCsv, sheetToHtml } from "xlsx-format";
const csv = sheetToCsv(sheet); // escapeFormulae defaults to true
const html = sheetToHtml(sheet); // sanitizeLinks defaults to trueReads are bounded by configurable limits for ZIP entries, total uncompressed bytes, per-entry bytes, XML text, and worksheet dimensions. Keep the defaults for untrusted uploads; raise ReadOptions limits explicitly only for large trusted files.
Styled report exports
Need polished XLSX output, but not the full ExcelJS object model? xlsx-format can write styled workbook reports with fonts, fills, borders, number formats, row heights, column widths, merged title rows, and frozen panes. Styling is opt-in with cellStyles: true, so existing unstyled exports keep their lean output.
import {
arrayToSheet,
createWorkbook,
freezePanes,
mergeCells,
setCellStyle,
setColumnWidth,
setRowHeight,
styleRange,
write,
type CellStyle,
} from "xlsx-format";
const titleStyle: CellStyle = {
font: { name: "Calibri", size: 14, bold: true, color: { argb: "FFFFFFFF" } },
fill: { patternType: "solid", fgColor: { argb: "FF1F4E79" } },
alignment: { vertical: "middle" },
};
const headerStyle: CellStyle = {
font: { bold: true, color: { argb: "FFFFFFFF" } },
fill: { patternType: "solid", fgColor: { argb: "FF2E75B6" } },
alignment: { horizontal: "center", vertical: "middle", wrapText: true },
};
const ws = arrayToSheet([
["Northstar Solar PPA - Q2 Report", null, null],
["Month", "Expected MWh", "Settlement"],
["Apr 2026", 12400, -18350],
]);
setCellStyle(ws["A1"], titleStyle);
styleRange(ws, "A2:C2", headerStyle);
mergeCells(ws, "A1:C1");
setRowHeight(ws, 0, 30);
setColumnWidth(ws, 0, 18);
freezePanes(ws, { ySplit: 2 });
const bytes = await write(createWorkbook(ws, "Overview"), {
type: "array",
cellStyles: true,
});See the Styled Workbooks guide for a full report export example.
Switching from SheetJS
The API is intentionally close to SheetJS. Three things change:
read()andwrite()return Promises. ZIP compression and decompression use Web Streams, while XML parsing, worksheet traversal, and final outputs use synchronous in-memory work. Move large or latency-sensitive jobs to a worker.- Named imports replace the namespace:
import { read } from "xlsx-format" - Utility names are camelCase:
sheetToJsoninstead ofXLSX.utils.sheet_to_json
- import XLSX from "xlsx";
+ import { read, write, sheetToJson, sheetToCsv } from "xlsx-format";
- const wb = XLSX.read(buffer);
+ const wb = await read(buffer);
- const rows = XLSX.utils.sheet_to_json(ws);
+ const rows = sheetToJson(ws);
- const buf = XLSX.write(wb, { type: "buffer", bookType: "xlsx" });
+ const buf = await write(wb, { type: "buffer" });Cell objects keep the same shape: { t: "n", v: 42, w: "42" } works exactly as before. For a full function mapping table, see the Migration Guide.
Acknowledgments
Based on the work of SheetJS, originally created by SheetJS LLC. Thank you to the SheetJS team and its contributors for building the foundation this library stands on.
License
Apache 2.0 -- see LICENSE for details.
Copyright (C) 2012-present SheetJS LLC (original work)
