hucre: a zero-dependency TypeScript spreadsheet engine for reading and writing XLSX, CSV and ODS
Project brief: Zero-dependency spreadsheet engine. Read & write XLSX, CSV, ODS. Pure TypeScript, works everywhere.
At a glance
- What is it?
- hucre is a pure TypeScript library that reads and writes XLSX, CSV, ODS, JSON, NDJSON and XML with no runtime dependencies. It fits edge runtimes and small bundles, but it does not evaluate formulas and its ODS writer drops most cell styling.
- Who is it for?
- Adopt hucre when you need spreadsheet parsing or generation inside a TypeScript service, an edge function or a browser bundle and you can live without formula evaluation. Do not adopt it if you need ODS output that preserves borders, alignment, column widths or freeze panes, or if you depend on top10 and aboveAverage conditional formatting attributes surviving a round trip.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 18, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem hucre solves: spreadsheet files without a runtime
Most spreadsheet work in a TypeScript codebase ends in one of two places. Either you pull in a large library that carries dependencies and a CommonJS build, or you shell out to a service. hucre targets the first case with a different constraint: the package declares zero dependencies, ships as ESM, and exposes subpath exports so an application that only parses CSV does not pay for the XLSX reader.
The audience is narrow and identifiable. It is for backend and edge developers who receive uploaded workbooks, for reporting jobs that generate XLSX on demand, and for browser applications that need to read a file the user selected without uploading it. The README's comparison table lists edge runtime support and CSP compliance as differentiators, which points at the same audience: code that runs where a native module or an eval-based parser is not an option.
The library also handles ODS, which is less common in JavaScript tooling. According to the README, ODS values, formulas and merges round-trip in full, while cell styling covers six facets: bold, italic, size, font colour, background colour and number format. Everything else in the ODS format is not modelled in either direction.
How hucre reads and writes a workbook
The API is split by format. The root entry point re-exports everything, and the subpaths `hucre/xlsx`, `hucre/csv`, `hucre/ods`, `hucre/json`, `hucre/xml` and `hucre/ooxml` expose individual formats. The package.json marks `sideEffects` as false, so a bundler can drop the formats you never import.
Reading returns a workbook object. The README example shows `readXlsx` accepting a buffer and returning `workbook.sheets`, where each sheet carries `name`, `rows`, and `merges`. Options include `sheets`, which filters by index, by name, or by a predicate; `readStyles`, which turns on style parsing; and `dateSystem`, set to `"auto"` to detect the 1900 or 1904 date system.
Writing goes the other way. `writeXlsx` takes a description of sheets, with column definitions that carry `header`, `key`, `width` and `numFmt`, plus a `data` array of plain objects. The library maps object keys to columns, so you describe the shape once and pass rows.
The design decision worth noting is that hucre does not evaluate formulas. The comparison table states this plainly, and it matches openpyxl and XlsxWriter, which also do not evaluate. Apache POI is listed as the one that does. If your pipeline needs computed values, you either read the cached values stored in the file or compute them yourself.
Installing hucre and writing your first XLSX
The README gives a single install command. It publishes to npm under the name `hucre`, and the package is ESM with type declarations at `./dist/index.d.mts`.
npm install hucreAfter install, the smallest useful program imports only the XLSX subpath. The README's tree-shaking section recommends `hucre/xlsx` when you do not need the other formats, and the size figures it publishes put `{ readXlsx }` from that subpath at 34 KB minified and gzipped.
import { readXlsx } from "hucre/xlsx"
const wb = await readXlsx(uint8Array, {
sheets: [0, "Products"],
readStyles: true,
dateSystem: "auto",
})
for (const sheet of wb.sheets) {
console.log(sheet.name)
console.log(sheet.rows)
}This filters the workbook down to sheet index 0 and any sheet named `Products`, parses cell styles, and auto-detects the date system. You should see one entry per matching sheet, with `rows` typed as `CellValue[][]`.
Writing uses a declarative sheet description. Column `numFmt` values are passed through to the file, which is how the `$#,##0.00` format below reaches Excel.
import { writeXlsx } from "hucre/xlsx"
const xlsx = await writeXlsx({
sheets: [
{
name: "Products",
columns: [
{ header: "Name", key: "name", width: 25 },
{ header: "Price", key: "price", width: 12, numFmt: "$#,##0.00" },
{ header: "Stock", key: "stock", width: 10 },
],
data: [
{ name: "Widget", price: 9.99, stock: 142 },
{ name: "Gadget", price: 24.5, stock: 87 },
],
},
],
})The result is an XLSX payload you can write to disk or return from an HTTP handler. The package also installs a binary named `hucre` pointing at `./dist/cli.mjs`, so a command line path exists, though the README excerpt does not document its flags.
Where hucre stops: conditional formatting, ODS styling and pivot values
The README is unusually candid about partial support, and this is the part to read before committing.
Conditional formatting covers 13 rule types, listed by name: `cellIs`, `expression`, `colorScale`, `dataBar`, `iconSet`, `containsText`, `notContainsText`, `beginsWith`, `endsWith`, `containsBlanks`, `notContainsBlanks`, `duplicateValues`, `uniqueValues`. Two more, `top10` and `aboveAverage`, round-trip only in their default form, because the writer emits no `rank`, `percent`, `bottom`, `aboveAverage`, `equalAverage` or `stdDev` attributes. `timePeriod` rules are dropped on read. A file that relies on those attributes will not come back the way it went in.
ODS is the sharper boundary. Values, formulas and merges survive, and the six styling facets listed earlier survive. Borders, alignment, column widths, freeze panes, validation, named ranges, images and page setup are not modelled in either direction. The README states the consequence directly: ODS to ODS is lossless, XLSX to ODS drops them.
Pivot tables are described as read and write with a skeleton. hucre writes the pivot cache, layout and relationships, but not the pre-computed value cells. Excel fills those in on first open. That works for a user opening the file, and fails for any pipeline that reads the output without Excel touching it first.
Formula evaluation is absent, as noted. If your service ingests a workbook and needs the result of a formula, hucre gives you the formula string, not a number.
hucre compared with SheetJS and ExcelJS
The README's own table places hucre against SheetJS CE, ExcelJS and xlsx-js-style. The differences it highlights are packaging and feature coverage rather than raw capability.
ExcelJS is listed with 9 dependencies and a CommonJS build, and the table marks it as not CSP compliant because it uses eval. That is the clearest fork in the road. If you are bundling for a browser under a strict Content Security Policy, or targeting an edge runtime, ExcelJS is the wrong tool and hucre is designed for exactly that gap.
SheetJS CE is listed as having zero dependencies but no npm publication, requiring installation from a CDN tarball. The table also marks styling, images and conditional formatting as Pro-only there, while hucre includes them. The bundle figures differ substantially: the README puts SheetJS CE at roughly 300 KB gzipped against 34 KB for `{ readXlsx }` from `hucre/xlsx`.
Against libraries in other languages, the relevant comparison is openpyxl and XlsxWriter. Both are Python-only, so the choice is really about where the code runs. hucre reads and writes XLSX, ODS and CSV; openpyxl and XlsxWriter are XLSX only. If your pipeline is already Python and you need chart generation across 9 or 15 types, hucre's chart support is round-trip only, which is a different thing.
Bundle size, licence and what maintenance looks like
hucre is MIT licensed. The repository ships a LICENSE file and package.json declares `"license": "MIT"`. For most commercial use that is permissive, but the usual caveat applies: the package also declares a funding link, and MIT gives you no warranty or support obligation from the author. Nothing in the README suggests a separate commercial licence or a paid tier, unlike the SheetJS Pro comparison in its own table.
The size story is enforced rather than advertised. The README states that four figures are measured by `pnpm size` and pinned in `scripts/size-budget.json`, and that CI fails when one grows past its budget. The four are `{ parseCsv, writeCsv }` from `hucre/csv` at 3.7 KB, `{ readXlsx }` at 34 KB, `{ readXlsx, writeXlsx }` at 68 KB, and the full library at 129 KB, all minified and gzipped. The README notes the previous figures had drifted because nothing enforced them. That is a concrete maintenance mechanism, and it is the kind of thing that usually rots.
The last push to the repository was on 2026-08-13, the same day v1.1.0 was released. The repository is not archived. There are two earlier releases in the repository's release list, v1.0.0 on 2026-08-04 and v0.6.2 on 2026-07-21, so the release cadence has been quick. The package also ships `MIGRATION.md` and `docs/PARITY.md` in its published files, which is where upgrade instructions and the feature parity matrix live. The README excerpt does not document rollback behaviour, so if you pin a version and need to go back, check `MIGRATION.md` rather than assuming a downgrade path.
Editorial conclusion
Adopt hucre when you need spreadsheet parsing or generation inside a TypeScript service, an edge function or a browser bundle and you can live without formula evaluation. Do not adopt it if you need ODS output that preserves borders, alignment, column widths or freeze panes, or if you depend on top10 and aboveAverage conditional formatting attributes surviving a round trip. Verify first that your input files fall inside the supported feature set by checking the parity documentation shipped in the package, and confirm the size budget for the entry points you import.
Frequently asked questions
Does hucre evaluate spreadsheet formulas?
No. The README's comparison table lists formula evaluation as not supported, matching openpyxl and XlsxWriter, and distinguishes hucre from Apache POI on that point. You get the formula string, not a computed value.
Can hucre read and write ODS files without losing formatting?
Only partly. Values, formulas and merges round-trip in full, and cell styling covers bold, italic, size, font colour, background colour and number format. Borders, alignment, column widths, freeze panes, validation, named ranges, images and page setup are not modelled in either direction, so ODS to ODS is lossless while XLSX to ODS drops them.
How large is hucre in a bundle?
It depends on which subpath you import. The README gives 3.7 KB gzipped for `{ parseCsv, writeCsv }` from `hucre/csv`, 34 KB for `{ readXlsx }`, 68 KB for `{ readXlsx, writeXlsx }`, and 129 KB for the entire library. These four figures are pinned in `scripts/size-budget.json` and checked by CI.
Community notes