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.
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 format | ESM + CJS buildsImport or require — both ship. |
|---|---|
| TypeScript | Strict, first-class typesA discriminated-union value model, not `any`. |
| Dependencies | One (fflate)A single tiny zip dep — no transitive baggage. |
| Distribution | npm-native, maintainedPublished to npm and actively maintained. |
| Peak memory @ 500k rows | 188 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.