typed-xlsx
Getting Started

Comparison

How typed-xlsx differs from SheetJS and ExcelJS, and when each one is the better choice.

SheetJS, ExcelJS and typed-xlsx can all write .xlsx files. They differ in what you write.

With SheetJS or ExcelJS you place values into cells. With typed-xlsx you describe a report as a typed schema, and the library places the cells. That makes typed-xlsx narrower, it only writes reports, and much stricter about them.

At a glance

typed-xlsxSheetJS (Community)ExcelJS
You writea schema typed against your rowsarrays and cell objectsworkbook, row and cell objects
Reads .xlsxnoyesyes
Other formatsnoCSV, XLS, ODS and many moreCSV
Cell styles on writeyesin SheetJS Proyes
Formulastyped DSL, references checked by TypeScriptstringsstrings
Summary and totals rowsdeclared per columnwritten by handwritten by hand
Native Excel tablesyesnoyes
Native chartstyped marks over your tablesnono
Pivot tablestyped fields, with pivot chartsnobasic
Streaming writesame schema, batch commitsnot for .xlsxseparate streaming writer
Runtime dependenciesnonenoneseveral

Where typed-xlsx is the better fit

The report is the contract. Columns, headers, formulas, styles and summaries live in one schema typed against your row type. Renaming a field breaks the build, not the export.

Formulas stay correct when columns move. You write refs.column("qty").mul(refs.column("unitPrice")); typed-xlsx writes =(C2*D2), or a structured reference inside an Excel table. Referencing a column that doesn't exist, or one declared later, is a type error.

One schema, many exports. The same schema serves different row sets, a different column selection per audience, a different theme, or a native Excel table, without copying column definitions.

Big exports use the same code. createWorkbookStream() takes the same schema as createWorkbook(). See Benchmarks for measured throughput.

Report features are built in. Grouped headers, sub-row expansion, summary rows, badges, checkboxes, sparklines, images, hyperlinks, validation dropdowns, conditional formats and protection are schema options rather than cell-by-cell code. Native charts and pivot tables are declared from the tables you already have, with their columns checked by TypeScript.

Where SheetJS or ExcelJS is the better fit

  • Reading files. typed-xlsx only writes. To parse uploads or import spreadsheets, use SheetJS or ExcelJS.
  • Other formats. SheetJS reads and writes far more formats than .xlsx.
  • Editing an existing workbook. Opening a file, changing it and saving it back is outside typed-xlsx's scope.
  • Free-form sheets. When the sheet isn't a table of records (a form, a dashboard laid out cell by cell, notes and rich text), a cell API is the more direct tool.
Copyright © 2026 Cyprien Thao. Released under the MIT License.