-
Notifications
You must be signed in to change notification settings - Fork 1
Architecture
ABCrimson edited this page Mar 2, 2026
·
6 revisions
modern-xlsx is a hybrid Rust WASM + TypeScript library for reading and writing XLSX files.
┌──────────────────────────────────────────┐
│ TypeScript API │
│ Workbook · Worksheet · Cell │
│ StyleBuilder · RichTextBuilder │
│ Utilities (dates, cell refs, CSV, JSON) │
└────────────────┬─────────────────────────┘
│ JSON string
┌────────────────┴─────────────────────────┐
│ WASM Bridge (wasm-bindgen) │
│ read() · write() · readJson() │
└────────────────┬─────────────────────────┘
│
┌────────────────┴─────────────────────────┐
│ Rust Core (modern-xlsx-core) │
│ ZIP (deflate) · XML (quick-xml SAX) │
│ SharedStringTable · Style resolution │
│ Content types · Relationships │
└──────────────────────────────────────────┘
Uint8Array → WASM read()
→ ZIP decompress (zip crate)
→ Parse XML parts (quick-xml SAX)
→ Build WorkbookData struct
→ Serialize to JSON (serde_json)
→ JSON.parse() in JS
→ Workbook class wraps raw data
Workbook.toBuffer()
→ Serialize to JSON (JSON.stringify)
→ WASM write()
→ Build SST from shared string cells
→ Generate XML parts (quick-xml Writer)
→ ZIP compress (zip crate, deflate)
→ Return Uint8Array
Data crosses the WASM boundary as JSON strings, not via serde_wasm_bindgen. Benchmarks show this is 8–13x faster for large workbooks because:
-
serde_jsonserialization in Rust is heavily optimized (itoa, ryu for numbers) -
JSON.parse()is one of the fastest built-in V8/SpiderMonkey operations - A single WASM boundary crossing replaces thousands of individual
wasm_bindgencalls
| Module | Purpose |
|---|---|
lib.rs |
WorkbookData, SheetData, CellData — shared types |
reader.rs |
Read orchestrator (ZIP → parse → WorkbookData) |
writer.rs |
Write orchestrator (WorkbookData → XML → ZIP) |
streaming.rs |
Streaming reader/writer for large files |
ooxml/ |
Individual OOXML part parsers |
number_format.rs |
Excel number format code parser |
errors.rs |
ModernXlsxError error type |
| Parser | OOXML Part |
|---|---|
shared_strings.rs |
xl/sharedStrings.xml |
styles.rs |
xl/styles.xml |
worksheet.rs |
xl/worksheets/sheet*.xml |
workbook.rs |
xl/workbook.xml |
relationships.rs |
*.rels files |
content_types.rs |
[Content_Types].xml |
doc_props.rs |
docProps/core.xml, docProps/app.xml
|
comments.rs |
xl/comments*.xml |
theme.rs |
xl/theme/theme1.xml |
calc_chain.rs |
xl/calcChain.xml |
- SAX parsing — quick-xml streams events, never builds a DOM tree
-
Vec::with_capacity()— pre-allocated parse buffers on all XML parsers -
push_entity()— zero-allocation XML entity resolution (writes into caller's buffer) -
from_utf8().unwrap_or_default()— avoids lossy conversion + allocation -
entries.remove()— moves data out of HashMap instead of cloning -
drain()— moves preserved entries instead of cloning large blobs - Binary search insertion — rows inserted in sorted order
-
itoa::Buffer— zero-allocation integer formatting in XML
| Component | Size |
|---|---|
| WASM binary | ~870 KB |
| JS wrapper | ~25 KB |
| Total | ~895 KB |
modern-xlsx v1.0.0
Getting Started
Guides
- Charts & Visualizations
- Formula Engine
- Table Layout Engine
- Tables & Print Layout
- Encryption
- Feature Comparison
Reference
Migration
Project