Try @alosha/xlsx

Build a real .xlsx workbook with styles, formulas, conditional formatting, comments and images — then read one back — entirely in your browser. Nothing is uploaded.

npm GitHub

Build & download

Pick the features to include, then generate a genuine, spec-valid workbook — open it in Excel, Numbers, Google Sheets or LibreOffice.

Read it back

Drop the file you just generated (or any .xlsx) — it's parsed with workbook.xlsx.load() and rendered below.

Drop an .xlsx here, or click to browse

Parsed locally — nothing leaves your device

Drop-in for ExcelJS

Already using ExcelJS? @alosha/xlsx/compat is an ExcelJS-shaped facade — same cell.type numbers, same style setters, same addRow behaviour. For most code, the migration is a single line:

- import ExcelJS from 'exceljs'
+ import ExcelJS from '@alosha/xlsx/compat'

A few behaviours differ (bytes instead of a Node Buffer, a dense 0-based worksheets array, and a couple of deferred features) — the migration guide lists them.

Why @alosha/xlsx

ExcelJS is excellent, MIT-licensed prior art — @alosha/xlsx is a clean-room rewrite that keeps the familiar API shape while modernising the internals. An honest, like-for-like comparison:

Module formatESM + CJS buildsImport or require — both ship.
TypeScriptStrict, first-class typesA discriminated-union value model, not `any`.
DependenciesOne (fflate)A single tiny zip dep — no transitive baggage.
Distributionnpm-native, maintainedPublished to npm and actively maintained.
Peak memory @ 500k rows188 MiB (streaming)≈15.6× lower than a buffered write (2.9 GiB), from BENCHMARKS.md.

Memory figures are the library's own published BENCHMARKS.md (500,000 rows × 5 cols): the streaming writer holds ≈15.6× less peak memory than a buffered write while sustaining ≈1.9× the throughput.

Install

Ships ESM + CJS + type declarations. One runtime dependency: fflate.