New:Microsoft Teams Notifications Are Now Available in Socket.Learn more →
Get Started

@uekichinos/quire

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@uekichinos/quire

Small, dependency-light .xlsx writer for Node and the browser. Worksheets, typed cells, styles, number formats, merged cells — no OOXML reader, no legacy bloat.

Source
npmnpm
Version
0.1.0
Version published
Weekly downloads
493
4008.33%
Maintainers
1
Weekly downloads
 
Created
Source

@uekichinos/quire

A small, dependency-light .xlsx writer for Node and the browser.

  • One runtime dependency — fflate for zip packaging
  • Writer only — no OOXML reader, so none of the parser-side CVE surface (zip bombs, path traversal, prototype pollution) that affects reader libraries
  • Worksheets · typed cells (string / number / boolean / Date / formula) · a de-duplicated style pool · merged cells · column widths · freeze panes · auto-filter · row heights
  • Returns a Uint8Array (or Blob); identical in Node and the browser
  • Deterministic output (stable bytes for stable input)

Install

npm install @uekichinos/quire

Usage

import { createWorkbook } from '@uekichinos/quire'

const wb = createWorkbook()
const sheet = wb.addWorksheet('Sales')

const header = { font: { bold: true, color: 'FFFFFF' }, fill: '2F5597' }
sheet.addRow(
  [
    { value: 'Product', style: header },
    { value: 'Revenue', style: header },
    { value: 'Updated', style: header },
  ],
)

sheet.addRow(['Widget', { value: 15003.4, style: { numFmt: '#,##0.00' } }, new Date(2024, 2, 1)])
sheet.addRow(['Gadget', { value: 2450, style: { numFmt: '#,##0.00' } }, new Date(2024, 2, 3)])

sheet.addRow(
  ['Total', { value: { formula: 'SUM(B2:B3)', result: 17453.4 } }],
  { style: { font: { bold: true }, border: { top: { style: 'thin' } } } },
)

// layout
sheet.merge('A1:C1')
sheet.setColumn(1, { width: 24 })
sheet.freeze({ ySplit: 1 })
sheet.autoFilter('A1:C1')
sheet.addRow(['tall row'], { height: 30 })
sheet.setCell('E1', 'note', { align: { wrapText: true } })

// …or up front
wb.addWorksheet('Q2', { columns: [{ width: 20 }], freeze: { ySplit: 1 }, autoFilter: 'A1:C1' })

const bytes = wb.xlsx() // Uint8Array

// Node
import { writeFileSync } from 'node:fs'
writeFileSync('sales.xlsx', bytes)

// Browser
const url = URL.createObjectURL(wb.blob())

API

createWorkbook(): Workbook

Workbook
addWorksheet(name, options?)options: { columns?, freeze?, autoFilter? }. Name: 1–31 chars, unique, no \ / ? * [ ] :
xlsx() → Uint8Arraydeterministic
blob() → Blobspreadsheetml.sheet mime
Worksheet (all chainable)
addRow(values, { style?, height? })values: CellInput[] — a bare value or { value, style }
setCell(ref, value, style?)write to any A1 reference
setRow(i, { style?, height? })style/size a row even with no cells
setColumn(i, { width?, hidden?, style? })1-based; column style resolves column < row < cell
merge(range)'A1:C1'; rejects single-cell / backwards / overlapping
freeze({ xSplit?, ySplit? })frozen panes; freeze({}) clears
autoFilter(range)header filter dropdowns

Cell values: string · number · boolean · Date · { formula, result? } · null. Dates use the 1900 serial system (default format yyyy-mm-dd). null / undefined cells are skipped but keep column position. Non-finite numbers and pre-1900 dates throw.

CellStyle: font (name, size, bold, italic, underline, color) · fill ('RRGGBB' / 'AARRGGBB') · align (horizontal, vertical, wrapText, indent) · border (top/right/bottom/left/all → { style, color? }) · numFmt (format code or built-in id). Every distinct style is interned once. Cell style merges over row style over column style, one nested level deep.

Run node examples/hello.mjs (after pnpm build) for a full example.

Scope

quire is not a drop-in ExcelJS replacement. It targets the common "export a styled spreadsheet" case with a tiny, auditable surface.

Not included (see PLAN.md): reading .xlsx, images, charts, pivot tables, data validation, conditional formatting, rich text, a streaming writer, .xls / .xlsb. A minimal reader for files from mainstream tools may come later.

Performance

In-memory; ~100k rows × 5 cols serialise in ~1 second. Comfortable for typical exports; for millions of rows, wait for a streaming writer or chunk across sheets.

License

MIT © uekichinos. Portions adapted from ExcelJS (MIT) — see NOTICE.

Keywords

uekichinos

FAQs

Package last updated on 06 Sep 2026

Related posts