{"id":47928268,"url":"https://github.com/productdevbook/hucre","last_synced_at":"2026-04-04T07:02:26.246Z","repository":{"id":347363050,"uuid":"1190903403","full_name":"productdevbook/hucre","owner":"productdevbook","description":"Zero-dependency spreadsheet engine. Read \u0026 write XLSX, CSV, ODS. Pure TypeScript, works everywhere.","archived":false,"fork":false,"pushed_at":"2026-03-27T16:00:47.000Z","size":1237,"stargazers_count":0,"open_issues_count":8,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-28T00:57:18.992Z","etag":null,"topics":["csv","csv-parser","esm","excel","ods","ods-parser","parser","spreadsheet","streaming","tree-shakeable","typescript","xlsx","xlsx-parser","xlsx-writer","zero-dependency"],"latest_commit_sha":null,"homepage":"https://hucre.productdevbook.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/productdevbook.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["productdevbook"]}},"created_at":"2026-03-24T18:22:34.000Z","updated_at":"2026-03-27T16:00:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/productdevbook/hucre","commit_stats":null,"previous_names":["productdevbook/hucre"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/productdevbook/hucre","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/productdevbook%2Fhucre","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/productdevbook%2Fhucre/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/productdevbook%2Fhucre/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/productdevbook%2Fhucre/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/productdevbook","download_url":"https://codeload.github.com/productdevbook/hucre/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/productdevbook%2Fhucre/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31390695,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T04:26:24.776Z","status":"ssl_error","status_checked_at":"2026-04-04T04:23:34.147Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csv","csv-parser","esm","excel","ods","ods-parser","parser","spreadsheet","streaming","tree-shakeable","typescript","xlsx","xlsx-parser","xlsx-writer","zero-dependency"],"created_at":"2026-04-04T07:02:23.882Z","updated_at":"2026-04-04T07:02:26.229Z","avatar_url":"https://github.com/productdevbook.png","language":"TypeScript","readme":"\u003cp align=\"center\"\u003e\n  \u003cbr\u003e\n  \u003cimg src=\".github/assets/cover.svg\" alt=\"hucre — Zero-dependency spreadsheet engine\" width=\"100%\"\u003e\n  \u003cbr\u003e\u003cbr\u003e\n  \u003cb style=\"font-size: 2em;\"\u003ehucre\u003c/b\u003e\n  \u003cbr\u003e\u003cbr\u003e\n  Zero-dependency spreadsheet engine.\n  \u003cbr\u003e\n  Read \u0026 write XLSX, CSV, ODS. Schema validation, streaming, round-trip preservation. Pure TypeScript, works everywhere.\n  \u003cbr\u003e\u003cbr\u003e\n  \u003ca href=\"https://npmjs.com/package/hucre\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/hucre?style=flat\u0026colorA=18181B\u0026colorB=34d399\" alt=\"npm version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://npmjs.com/package/hucre\"\u003e\u003cimg src=\"https://img.shields.io/npm/dm/hucre?style=flat\u0026colorA=18181B\u0026colorB=34d399\" alt=\"npm downloads\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://bundlephobia.com/result?p=hucre\"\u003e\u003cimg src=\"https://img.shields.io/bundlephobia/minzip/hucre?style=flat\u0026colorA=18181B\u0026colorB=34d399\" alt=\"bundle size\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/productdevbook/hucre/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/productdevbook/hucre?style=flat\u0026colorA=18181B\u0026colorB=34d399\" alt=\"license\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Quick Start\n\n```sh\nnpm install hucre\n```\n\n```ts\nimport { readXlsx, writeXlsx } from \"hucre\";\n\n// Read an XLSX file\nconst workbook = await readXlsx(buffer);\nconsole.log(workbook.sheets[0].rows);\n\n// Write an XLSX file\nconst xlsx = await writeXlsx({\n  sheets: [\n    {\n      name: \"Products\",\n      columns: [\n        { header: \"Name\", key: \"name\", width: 25 },\n        { header: \"Price\", key: \"price\", width: 12, numFmt: \"$#,##0.00\" },\n        { header: \"Stock\", key: \"stock\", width: 10 },\n      ],\n      data: [\n        { name: \"Widget\", price: 9.99, stock: 142 },\n        { name: \"Gadget\", price: 24.5, stock: 87 },\n      ],\n    },\n  ],\n});\n```\n\n## Tree Shaking\n\nImport only what you need:\n\n```ts\nimport { readXlsx, writeXlsx } from \"hucre/xlsx\"; // XLSX only (~14 KB gzipped)\nimport { parseCsv, writeCsv } from \"hucre/csv\"; // CSV only (~2 KB gzipped)\n```\n\n## Why hucre?\n\n### vs JavaScript / TypeScript Libraries\n\n|                         | hucre     | SheetJS CE    | ExcelJS   | xlsx-js-style |\n| ----------------------- | --------- | ------------- | --------- | ------------- |\n| **Dependencies**        | 0         | 0\\*           | 12 (CVEs) | 0\\*           |\n| **Bundle (gzip)**       | ~18 KB    | ~300 KB       | ~500 KB   | ~300 KB       |\n| **ESM native**          | Yes       | Partial       | No (CJS)  | Partial       |\n| **TypeScript**          | Native    | Bolted-on     | Bolted-on | Bolted-on     |\n| **Edge runtime**        | Yes       | No            | No        | No            |\n| **CSP compliant**       | Yes       | Yes           | No (eval) | Yes           |\n| **npm published**       | Yes       | No (CDN only) | Stale     | Yes           |\n| **Read + Write**        | Yes       | Yes (Pro $)   | Yes       | Yes           |\n| **Styling**             | Yes       | No (Pro $)    | Yes       | Yes           |\n| **Cond. formatting**    | Yes (all) | No (Pro $)    | Partial   | No            |\n| **Stream read + write** | Yes       | CSV only      | Yes       | CSV only      |\n| **ODS support**         | Yes       | Yes           | No        | Yes           |\n| **Round-trip**          | Yes       | Partial       | Partial   | Partial       |\n| **Sparklines**          | Yes       | No            | No        | No            |\n| **Tables**              | Yes       | Yes           | Yes       | Yes           |\n| **Images**              | Yes       | No (Pro $)    | Yes       | No            |\n\n\\* SheetJS removed itself from npm; must install from CDN tarball.\n\n### vs Libraries in Other Languages\n\n|                       | hucre (TS)   | openpyxl (Py) | XlsxWriter (Py) | rust_xlsxwriter | Apache POI (Java) |\n| --------------------- | ------------ | ------------- | --------------- | --------------- | ----------------- |\n| **Read XLSX**         | Yes          | Yes           | No              | No              | Yes               |\n| **Write XLSX**        | Yes          | Yes           | Yes             | Yes             | Yes               |\n| **Streaming**         | Read+Write   | Write-only    | No              | const_memory    | SXSSF (write)     |\n| **Charts**            | Round-trip   | 15+ types     | 9 types         | 12+ types       | Limited           |\n| **Pivot tables**      | No           | Read-only     | No              | No              | Limited           |\n| **Cond. formatting**  | Yes (all)    | Yes           | Yes             | Yes             | Yes               |\n| **Sparklines**        | Yes          | No            | Yes             | Yes             | No                |\n| **Formula eval**      | No           | No            | No              | No              | Yes               |\n| **Multi-format**      | XLSX/ODS/CSV | XLSX only     | XLSX only       | XLSX only       | XLS/XLSX          |\n| **Zero dependencies** | Yes          | lxml optional | No              | Yes             | No                |\n\n## Features\n\n### Reading\n\n```ts\nimport { readXlsx } from \"hucre/xlsx\";\n\nconst wb = await readXlsx(uint8Array, {\n  sheets: [0, \"Products\"], // Filter sheets by index or name\n  readStyles: true, // Parse cell styles\n  dateSystem: \"auto\", // Auto-detect 1900/1904\n});\n\nfor (const sheet of wb.sheets) {\n  console.log(sheet.name); // \"Products\"\n  console.log(sheet.rows); // CellValue[][]\n  console.log(sheet.merges); // MergeRange[]\n}\n```\n\nSupported cell types: strings, numbers, booleans, dates, formulas, rich text, errors, inline strings.\n\n### Writing\n\n```ts\nimport { writeXlsx } from \"hucre/xlsx\";\n\nconst buffer = await writeXlsx({\n  sheets: [\n    {\n      name: \"Report\",\n      columns: [\n        { header: \"Date\", key: \"date\", width: 15, numFmt: \"yyyy-mm-dd\" },\n        { header: \"Revenue\", key: \"revenue\", width: 15, numFmt: \"$#,##0.00\" },\n        { header: \"Active\", key: \"active\", width: 10 },\n      ],\n      data: [\n        { date: new Date(\"2026-01-15\"), revenue: 12500, active: true },\n        { date: new Date(\"2026-01-16\"), revenue: 8900, active: false },\n      ],\n      freezePane: { rows: 1 },\n      autoFilter: { range: \"A1:C3\" },\n    },\n  ],\n  defaultFont: { name: \"Calibri\", size: 11 },\n});\n```\n\nFeatures: cell styles, auto column widths, merged cells, freeze/split panes, auto-filter with criteria, data validation, hyperlinks, images (PNG/JPEG/GIF/SVG/WebP), comments, tables, conditional formatting (cellIs/colorScale/dataBar/iconSet), named ranges, print settings, page breaks, sheet protection, workbook protection, rich text, shared/array/dynamic formulas, sparklines, textboxes, background images, number formats, hidden sheets, HTML/Markdown/JSON/TSV export, template engine.\n\n### Auto Column Width\n\n```ts\nconst buffer = await writeXlsx({\n  sheets: [\n    {\n      name: \"Products\",\n      columns: [\n        { header: \"Name\", key: \"name\", autoWidth: true },\n        { header: \"Price\", key: \"price\", autoWidth: true, numFmt: \"$#,##0.00\" },\n        { header: \"SKU\", key: \"sku\", autoWidth: true },\n      ],\n      data: products,\n    },\n  ],\n});\n```\n\nCalculates optimal column widths from cell content — font-aware, handles CJK double-width characters, number formats, min/max constraints.\n\n### Data Validation\n\n```ts\nconst buffer = await writeXlsx({\n  sheets: [\n    {\n      name: \"Sheet1\",\n      rows: [\n        [\"Status\", \"Quantity\"],\n        [\"active\", 10],\n      ],\n      dataValidations: [\n        {\n          type: \"list\",\n          values: [\"active\", \"inactive\", \"draft\"],\n          range: \"A2:A100\",\n          showErrorMessage: true,\n          errorTitle: \"Invalid\",\n          errorMessage: \"Pick from the list\",\n        },\n        {\n          type: \"whole\",\n          operator: \"between\",\n          formula1: \"0\",\n          formula2: \"1000\",\n          range: \"B2:B100\",\n        },\n      ],\n    },\n  ],\n});\n```\n\n### Hyperlinks\n\n```ts\nconst buffer = await writeXlsx({\n  sheets: [\n    {\n      name: \"Links\",\n      rows: [[\"Visit Google\", \"Go to Sheet2\"]],\n      cells: new Map([\n        [\n          \"0,0\",\n          {\n            value: \"Visit Google\",\n            type: \"string\",\n            hyperlink: { target: \"https://google.com\", tooltip: \"Open Google\" },\n          },\n        ],\n        [\n          \"0,1\",\n          {\n            value: \"Go to Sheet2\",\n            type: \"string\",\n            hyperlink: { target: \"\", location: \"Sheet2!A1\" },\n          },\n        ],\n      ]),\n    },\n  ],\n});\n```\n\n### Streaming\n\nProcess large files row-by-row without loading everything into memory:\n\n```ts\nimport { streamXlsxRows, XlsxStreamWriter } from \"hucre/xlsx\";\n\n// Stream read — async generator yields rows one at a time\nfor await (const row of streamXlsxRows(buffer)) {\n  console.log(row.index, row.values);\n}\n\n// Stream write — add rows incrementally\nconst writer = new XlsxStreamWriter({\n  name: \"BigData\",\n  columns: [{ header: \"ID\" }, { header: \"Value\" }],\n  freezePane: { rows: 1 },\n});\nfor (let i = 0; i \u003c 100_000; i++) {\n  writer.addRow([i + 1, Math.random()]);\n}\nconst buffer = await writer.finish();\n```\n\n### ODS (OpenDocument)\n\n```ts\nimport { readOds, writeOds } from \"hucre/ods\";\n\nconst wb = await readOds(buffer);\nconst ods = await writeOds({ sheets: [{ name: \"Sheet1\", rows: [[\"Hello\", 42]] }] });\n```\n\n### Round-trip Preservation\n\nOpen, modify, save — without losing charts, macros, or features hucre doesn't natively handle:\n\n```ts\nimport { openXlsx, saveXlsx } from \"hucre/xlsx\";\n\nconst workbook = await openXlsx(buffer);\nworkbook.sheets[0].rows[0][0] = \"Updated!\";\nconst output = await saveXlsx(workbook); // Charts, VBA, themes preserved\n```\n\n### Unified API\n\nAuto-detect format and work with simple helpers:\n\n```ts\nimport { read, write, readObjects, writeObjects } from \"hucre\";\n\n// Auto-detect XLSX vs ODS\nconst wb = await read(buffer);\n\n// Quick: file → array of objects\nconst products = await readObjects\u003c{ name: string; price: number }\u003e(buffer);\n\n// Quick: objects → XLSX\nconst xlsx = await writeObjects(products, { sheetName: \"Products\" });\n```\n\n### CLI\n\n```bash\nnpx hucre convert input.xlsx output.csv\nnpx hucre convert input.csv output.xlsx\nnpx hucre inspect file.xlsx\nnpx hucre inspect file.xlsx --sheet 0\nnpx hucre validate data.xlsx --schema schema.json\n```\n\n### Sheet Operations\n\nManipulate sheet data in memory:\n\n```ts\nimport { insertRows, deleteRows, cloneSheet, moveSheet } from \"hucre\";\n\ninsertRows(sheet, 5, 3); // Insert 3 rows at position 5\ndeleteRows(sheet, 0, 1); // Delete first row\nconst copy = cloneSheet(sheet, \"Copy\"); // Deep clone\nmoveSheet(workbook, 0, 2); // Reorder sheets\n```\n\n### HTML \u0026 Markdown Export\n\n```ts\nimport { toHtml, toMarkdown } from \"hucre\";\n\nconst html = toHtml(workbook.sheets[0], {\n  headerRow: true,\n  styles: true,\n  classes: true,\n});\n\nconst md = toMarkdown(workbook.sheets[0]);\n// | Name   | Price  | Stock |\n// |--------|-------:|------:|\n// | Widget |   9.99 |   142 |\n```\n\n### Number Format Renderer\n\n```ts\nimport { formatValue } from \"hucre\";\n\nformatValue(1234.5, \"#,##0.00\"); // \"1,234.50\"\nformatValue(0.15, \"0%\"); // \"15%\"\nformatValue(44197, \"yyyy-mm-dd\"); // \"2021-01-01\"\nformatValue(1234, \"$#,##0\"); // \"$1,234\"\nformatValue(0.333, \"# ?/?\"); // \"1/3\"\n```\n\n### Cell Utilities\n\n```ts\nimport { parseCellRef, cellRef, colToLetter, rangeRef } from \"hucre\";\n\nparseCellRef(\"AA15\"); // { row: 14, col: 26 }\ncellRef(14, 26); // \"AA15\"\ncolToLetter(26); // \"AA\"\nrangeRef(0, 0, 9, 3); // \"A1:D10\"\n```\n\n### Builder API\n\nFluent method-chaining interface:\n\n```ts\nimport { WorkbookBuilder } from \"hucre\";\n\nconst xlsx = await WorkbookBuilder.create()\n  .addSheet(\"Products\")\n  .columns([\n    { header: \"Name\", key: \"name\", autoWidth: true },\n    { header: \"Price\", key: \"price\", numFmt: \"$#,##0.00\" },\n  ])\n  .row([\"Widget\", 9.99])\n  .row([\"Gadget\", 24.5])\n  .freeze(1)\n  .done()\n  .build();\n```\n\n### Template Engine\n\nFill `{{placeholders}}` in existing XLSX templates:\n\n```ts\nimport { openXlsx, saveXlsx, fillTemplate } from \"hucre\";\n\nconst workbook = await openXlsx(templateBuffer);\nfillTemplate(workbook, {\n  company: \"Acme Inc\",\n  date: new Date(),\n  total: 12500,\n});\nconst output = await saveXlsx(workbook);\n```\n\n### JSON Export\n\n```ts\nimport { toJson } from \"hucre\";\n\ntoJson(sheet, { format: \"objects\" }); // [{Name:\"Widget\", Price:9.99}, ...]\ntoJson(sheet, { format: \"columns\" }); // {Name:[\"Widget\"], Price:[9.99]}\ntoJson(sheet, { format: \"arrays\" }); // {headers:[...], data:[[...]]}\n```\n\n### CSV\n\n```ts\nimport { parseCsv, parseCsvObjects, writeCsv, detectDelimiter } from \"hucre/csv\";\n\n// Parse — auto-detects delimiter, handles RFC 4180 edge cases\nconst rows = parseCsv(csvString, { typeInference: true });\n\n// Parse with headers — returns typed objects\nconst { data, headers } = parseCsvObjects(csvString, { header: true });\n\n// Write\nconst csv = writeCsv(rows, { delimiter: \";\", bom: true });\n\n// Detect delimiter\ndetectDelimiter(csvString); // \",\" or \";\" or \"\\t\" or \"|\"\n```\n\n### Schema Validation\n\nValidate imported data with type coercion, pattern matching, and error collection:\n\n```ts\nimport { validateWithSchema } from \"hucre\";\nimport { parseCsv } from \"hucre/csv\";\n\nconst rows = parseCsv(csvString);\n\nconst result = validateWithSchema(\n  rows,\n  {\n    \"Product Name\": { type: \"string\", required: true },\n    Price: { type: \"number\", required: true, min: 0 },\n    SKU: { type: \"string\", pattern: /^[A-Z]{3}-\\d{4}$/ },\n    Stock: { type: \"integer\", min: 0, default: 0 },\n    Status: { type: \"string\", enum: [\"active\", \"inactive\", \"draft\"] },\n  },\n  { headerRow: 1 },\n);\n\nconsole.log(result.data); // Validated \u0026 coerced objects\nconsole.log(result.errors); // [{ row: 3, field: \"Price\", message: \"...\", value: \"abc\" }]\n```\n\nSchema field options:\n\n| Option        | Type                                                       | Description                             |\n| ------------- | ---------------------------------------------------------- | --------------------------------------- |\n| `type`        | `\"string\" \\| \"number\" \\| \"integer\" \\| \"boolean\" \\| \"date\"` | Target type (with coercion)             |\n| `required`    | `boolean`                                                  | Reject null/empty values                |\n| `pattern`     | `RegExp`                                                   | Regex validation (strings)              |\n| `min`         | `number`                                                   | Min value (numbers) or length (strings) |\n| `max`         | `number`                                                   | Max value (numbers) or length (strings) |\n| `enum`        | `unknown[]`                                                | Allowed values                          |\n| `default`     | `unknown`                                                  | Default for null/empty                  |\n| `validate`    | `(v) =\u003e boolean \\| string`                                 | Custom validator                        |\n| `transform`   | `(v) =\u003e unknown`                                           | Post-validation transform               |\n| `column`      | `string`                                                   | Column header name                      |\n| `columnIndex` | `number`                                                   | Column index (0-based)                  |\n\n### Date Utilities\n\nTimezone-safe Excel date serial number conversion:\n\n```ts\nimport { serialToDate, dateToSerial, isDateFormat, formatDate } from \"hucre\";\n\nserialToDate(44197); // 2021-01-01T00:00:00.000Z\ndateToSerial(new Date(\"2021-01-01\")); // 44197\nisDateFormat(\"yyyy-mm-dd\"); // true\nisDateFormat(\"#,##0.00\"); // false\nformatDate(new Date(), \"yyyy-mm-dd\"); // \"2026-03-24\"\n```\n\nHandles the Lotus 1-2-3 bug (serial 60), 1900/1904 date systems, and time fractions correctly.\n\n## Platform Support\n\nhucre works everywhere — no Node.js APIs (`fs`, `crypto`, `Buffer`) in core.\n\n| Runtime               | Status       |\n| --------------------- | ------------ |\n| Node.js 18+           | Full support |\n| Deno                  | Full support |\n| Bun                   | Full support |\n| Modern browsers       | Full support |\n| Cloudflare Workers    | Full support |\n| Vercel Edge Functions | Full support |\n| Web Workers           | Full support |\n\n## Architecture\n\n```\nhucre (~37 KB gzipped)\n├── zip/            Zero-dep DEFLATE/inflate + ZIP read/write\n├── xml/            SAX parser + XML writer (CSP-compliant, no eval)\n├── xlsx/\n│   ├── reader      Shared strings, styles, worksheets, relationships\n│   ├── writer      Styles, shared strings, drawing, tables, comments\n│   ├── roundtrip   Open → modify → save with preservation\n│   ├── stream-*    Streaming reader (AsyncGenerator) + writer\n│   └── auto-width  Font-aware column width calculation\n├── ods/            OpenDocument Spreadsheet read/write\n├── csv/            RFC 4180 parser/writer + streaming\n├── export/         HTML, Markdown, JSON, TSV output + HTML import\n├── hucre           Unified read/write API, format auto-detect\n├── builder         Fluent WorkbookBuilder / SheetBuilder API\n├── template        {{placeholder}} template engine\n├── sheet-ops       Insert/delete/move/sort/find/replace, clone, copy\n├── cell-utils      parseCellRef, colToLetter, parseRange, isInRange\n├── image           imageFromBase64 utility\n├── worker          Web Worker serialization helpers\n├── _date           Timezone-safe serial ↔ Date, Lotus bug, 1900/1904\n├── _format         Number format renderer (locale-aware)\n├── _schema         Schema validation, type coercion, error collection\n└── cli             Convert, inspect, validate (citty + consola)\n```\n\nZero dependencies. Pure TypeScript. The ZIP engine uses `CompressionStream`/`DecompressionStream` Web APIs with a pure TS fallback.\n\n## API Reference\n\n### High-level\n\n| Function                       | Description                                       |\n| ------------------------------ | ------------------------------------------------- |\n| `read(input, options?)`        | Auto-detect format (XLSX/ODS), returns `Workbook` |\n| `write(options)`               | Write XLSX or ODS (via `format` option)           |\n| `readObjects(input, options?)` | File → array of objects (first row = headers)     |\n| `writeObjects(data, options?)` | Objects → XLSX/ODS                                |\n\n### XLSX\n\n| Function                          | Description                                   |\n| --------------------------------- | --------------------------------------------- |\n| `readXlsx(input, options?)`       | Parse XLSX from `Uint8Array \\| ArrayBuffer`   |\n| `writeXlsx(options)`              | Generate XLSX, returns `Uint8Array`           |\n| `openXlsx(input, options?)`       | Open for round-trip (preserves unknown parts) |\n| `saveXlsx(workbook)`              | Save round-trip workbook back to XLSX         |\n| `streamXlsxRows(input, options?)` | AsyncGenerator yielding rows one at a time    |\n| `XlsxStreamWriter`                | Class for incremental row-by-row XLSX writing |\n\n### ODS\n\n| Function                   | Description                          |\n| -------------------------- | ------------------------------------ |\n| `readOds(input, options?)` | Parse ODS (OpenDocument Spreadsheet) |\n| `writeOds(options)`        | Generate ODS                         |\n| `streamOdsRows(input)`     | AsyncGenerator yielding ODS rows     |\n\n### CSV\n\n| Function                           | Description                                  |\n| ---------------------------------- | -------------------------------------------- |\n| `parseCsv(input, options?)`        | Parse CSV string → `CellValue[][]`           |\n| `parseCsvObjects(input, options?)` | Parse CSV with headers → `{ data, headers }` |\n| `writeCsv(rows, options?)`         | Write `CellValue[][]` → CSV string           |\n| `writeCsvObjects(data, options?)`  | Write objects → CSV string                   |\n| `detectDelimiter(input)`           | Auto-detect delimiter character              |\n| `streamCsvRows(input, options?)`   | Generator yielding CSV rows                  |\n| `CsvStreamWriter`                  | Class for incremental CSV writing            |\n| `writeTsv(rows, options?)`         | Write TSV (tab-separated)                    |\n| `fetchCsv(url, options?)`          | Fetch and parse CSV from URL                 |\n\n### Sheet Operations\n\n| Function                                | Description                     |\n| --------------------------------------- | ------------------------------- |\n| `insertRows(sheet, index, count)`       | Insert rows, shift down         |\n| `deleteRows(sheet, index, count)`       | Delete rows, shift up           |\n| `insertColumns(sheet, index, count)`    | Insert columns, shift right     |\n| `deleteColumns(sheet, index, count)`    | Delete columns, shift left      |\n| `moveRows(sheet, from, count, to)`      | Move rows                       |\n| `cloneSheet(sheet, name)`               | Deep clone a sheet              |\n| `copySheetToWorkbook(sheet, wb, name?)` | Copy sheet between workbooks    |\n| `copyRange(sheet, source, target)`      | Copy cell range within sheet    |\n| `moveSheet(wb, from, to)`               | Reorder sheets                  |\n| `removeSheet(wb, index)`                | Remove a sheet                  |\n| `sortRows(sheet, col, order?)`          | Sort rows by column             |\n| `findCells(sheet, predicate)`           | Find cells by value or function |\n| `replaceCells(sheet, find, replace)`    | Find and replace values         |\n\n### Export\n\n| Function                      | Description                                      |\n| ----------------------------- | ------------------------------------------------ |\n| `toHtml(sheet, options?)`     | HTML `\u003ctable\u003e` with styles, a11y, dark/light CSS |\n| `toMarkdown(sheet, options?)` | Markdown table with auto-alignment               |\n| `toJson(sheet, options?)`     | JSON (objects, arrays, or columns format)        |\n| `fromHtml(html, options?)`    | Parse HTML table string → Sheet                  |\n\n### Builder\n\n| Function                       | Description                             |\n| ------------------------------ | --------------------------------------- |\n| `WorkbookBuilder.create()`     | Fluent API for building workbooks       |\n| `fillTemplate(workbook, data)` | Replace `{{placeholders}}` in templates |\n\n### Formatting \u0026 Utilities\n\n| Function                                     | Description                              |\n| -------------------------------------------- | ---------------------------------------- |\n| `formatValue(value, numFmt, options?)`       | Apply Excel number format (locale-aware) |\n| `validateWithSchema(rows, schema, options?)` | Validate \u0026 coerce data with schema       |\n| `serialToDate(serial, is1904?)`              | Excel serial → Date (UTC)                |\n| `dateToSerial(date, is1904?)`                | Date → Excel serial                      |\n| `isDateFormat(numFmt)`                       | Check if format string is date           |\n| `formatDate(date, format)`                   | Format Date with Excel format string     |\n| `parseCellRef(ref)`                          | \"AA15\" → `{ row: 14, col: 26 }`          |\n| `cellRef(row, col)`                          | `(14, 26)` → \"AA15\"                      |\n| `colToLetter(col)`                           | `26` → \"AA\"                              |\n| `rangeRef(r1, c1, r2, c2)`                   | `(0,0,9,3)` → \"A1:D10\"                   |\n\n### Web Worker Helpers\n\n| Function                    | Description                                                          |\n| --------------------------- | -------------------------------------------------------------------- |\n| `serializeWorkbook(wb)`     | Convert Workbook for `postMessage` (Maps → objects, Dates → strings) |\n| `deserializeWorkbook(data)` | Restore Workbook from serialized form                                |\n| `WORKER_SAFE_FUNCTIONS`     | List of all hucre functions safe for Web Workers (all of them)       |\n\n## Development\n\n```sh\npnpm install\npnpm dev          # vitest watch\npnpm test         # lint + typecheck + test\npnpm build        # obuild (minified, tree-shaken)\npnpm lint:fix     # oxlint + oxfmt\npnpm typecheck    # tsgo\n```\n\n## Contributing\n\nContributions are welcome! Please [open an issue](https://github.com/productdevbook/hucre/issues) or submit a PR.\n\n127 of 135 tracked features are implemented. See the [issue tracker](https://github.com/productdevbook/hucre/issues) for the roadmap.\n\n### Roadmap\n\n**Report Builder** — Enhanced `writeObjects` with column mapping, formula helpers, conditional style rules, summary rows, style presets, column groups, sub-row expansion, Excel table auto-generation, streaming object writes.\n\n**Upcoming Engine Features:**\n\n- Chart creation (bar, line, pie, scatter, area + subtypes)\n- XLS BIFF8 read (legacy Excel 97-2003)\n- XLSB binary format read\n- Formula evaluation engine\n- File encryption/decryption (AES-256, MS-OFFCRYPTO)\n- Pivot table creation\n- Threaded comments (Excel 365+)\n- Checkboxes (Excel 2024+)\n- VBA/macro injection\n- Slicers \u0026 timeline filters\n- R1C1 notation support\n- Accessibility helpers (WCAG 2.1 AA)\n\n## License\n\n[MIT](./LICENSE) — Made by [productdevbook](https://github.com/productdevbook)\n","funding_links":["https://github.com/sponsors/productdevbook"],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fproductdevbook%2Fhucre","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fproductdevbook%2Fhucre","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fproductdevbook%2Fhucre/lists"}