v0.6.0 — MIT Licensed

Excel files,
handled right.

High-performance XLSX read/write for JavaScript and TypeScript. Full styling, validation, and formatting — powered by Rust + WASM. Everything SheetJS Pro charges for, free and open source.

Get Started View on GitHub
$ npm install modern-xlsx
4.7x
Faster reads vs SheetJS
~870 KB
WASM binary size
0
Runtime dependencies
437
Tests (Rust + TypeScript)

Features

Everything you need for production XLSX handling, without the paywall.

Cell Styling

Fonts, fills, borders, alignment, text rotation, shrink-to-fit. Fluent builder API produces style indices for any cell.

Number Formats

Built-in Excel format codes plus custom formats. Dates, currency, percentages, scientific notation — all rendered correctly.

Data Validation

List, whole number, decimal, date, time, text length, and custom formula validators with error messages.

Conditional Formatting

Color scales, data bars, icon sets, and formula-based rules. Read and write preserving all OOXML attributes.

Frozen Panes

Freeze rows, columns, or both. Maintains scroll position for large worksheets.

🔗

Hyperlinks

Internal sheet links, external URLs, email links — with display text and tooltips.

💬

Comments & Notes

Add, read, and remove cell comments with author attribution.

🔒

Sheet Protection

Protect worksheets with granular permissions — lock formatting, insertion, deletion, sorting, and filtering independently.

🔐

Encryption

Read and write password-protected XLSX files. ECMA-376 Agile Encryption with AES-256 and SHA-512.

📄

Page Setup

Paper size, orientation, margins, headers, footers — full print configuration.

🕒

Temporal API

First-class support for the Temporal API alongside classic Date objects. Future-proof date handling.

WASM Performance

Rust core compiled to WASM. ZIP decompression and XML parsing run at near-native speed inside the WASM sandbox.

📦

Tree-shakable ESM

Pure ESM with zero runtime dependencies. Import only what you need — bundlers eliminate the rest.

Performance

Benchmarked with a 100,000-row workbook. Node.js, single thread.

Read 100K
1,377 ms
5,942 ms
Write 10K
469 ms
645 ms
Write 100K (batch)
1,172 ms
6,248 ms
aoaToSheet 50K
242 ms
508 ms
Read 10K
156 ms
732 ms
modern-xlsx
SheetJS CE

Quick Start

Create a styled spreadsheet in under 30 lines.

example.ts
import { initWasm, Workbook, readFile } from 'modern-xlsx';

await initWasm();

// Create a new workbook
const wb = new Workbook();
const ws = wb.addSheet('Sales');

ws.cell('A1').value = 'Product';
ws.cell('B1').value = 'Revenue';
ws.cell('A2').value = 'Widget';
ws.cell('B2').value = 9999.99;

// Style headers
const header = wb.createStyle()
  .font({ bold: true, size: 14, color: '1F4E79' })
  .fill({ pattern: 'solid', fgColor: 'D6E4F0' })
  .alignment({ horizontal: 'center' })
  .build(wb.styles);

ws.cell('A1').styleIndex = header;
ws.cell('B1').styleIndex = header;

// Currency format
const currency = wb.createStyle()
  .numberFormat('$#,##0.00')
  .build(wb.styles);
ws.cell('B2').styleIndex = currency;

await wb.toFile('sales.xlsx');

// Read an existing file
const existing = await readFile('report.xlsx');
console.log(existing.getSheet('Sheet1')?.cell('A1').value);

API Reference

Full documentation available in the package README.

CategoryFunctions / Classes
Core initWasm() · Workbook · Worksheet · Cell
I/O readFile() · readBuffer() · toFile() · toBuffer() · writeBlob()
Styles StyleBuilder.font() .fill() .border() .alignment() .numberFormat() .build()
Conversions aoaToSheet() · jsonToSheet() · sheetToJson() · sheetToCsv() · sheetToHtml()
Dates dateToSerial() · serialToDate() · isDateFormatId()
Formatting formatCell() · getBuiltinFormat()
Cell Refs encodeCellRef() · decodeCellRef() · encodeRange() · decodeRange()
Rich Text RichTextBuilder.text() .bold() .italic() .styled() .build()

Architecture

Hybrid Rust + TypeScript design for maximum performance and developer experience.

TypeScript API
Workbook · Worksheet · Cell · StyleBuilder
↓ JSON ↓
wasm-bindgen Bridge
Rust Core — OOXML Parser & Writer
quick-xml (SAX) · zip (deflate) · SharedStringTable
Data crosses the WASM boundary as JSON strings — 8–13x faster than serde_wasm_bindgen for large workbooks (100K+ rows). The Rust core handles ZIP compression, SAX-style XML parsing, shared string table construction, and style resolution. The writer builds the SST inline during XML generation, avoiding a full worksheet clone.

Comparison

How modern-xlsx stacks up against SheetJS Community and Pro editions.

Featuremodern-xlsxSheetJS CESheetJS Pro
Read / write XLSXFreeFreePaid
Cell stylingFreeNo
Number formatsFreeRead only
Data validationFreeNo
Conditional formattingFreeNo
CommentsFreeRead only
Rich textFreeNo
Sheet protectionFreeRead only
Frozen panesFreePartial
Temporal API datesYesNoNo
Available on npmYesCDN onlyNo
Tree-shakable ESMYesNoNo
TypeScript typesBuilt-inPartialPartial
WASM-acceleratedYesNoNo
OOXML validation & repairYesNoNo
Barcode & QR code generationYesNoNo
Image embeddingYesNo
Encryption (password protection)YesNoNo