Sheets, columns, row counts, and the activeSheet id.
presentation
"spreadsheet" | "data-grid"
"spreadsheet"
Positional A/B/C headers or semantic Column.header labels. Addressing and data rows are unchanged.
data
ColumnarData
undefined
Eager, in-memory, column-major values. Pass this ordatasource.
datasource
DataSource
undefined
Lazy, paged async source; rows fetched per visible window. See Datasources.
datasourceStorage
DataSourceStorageOptions
{ mode: "dense" }
Use { mode: "paged", chunkRows?, cacheBytes? } for allocation-lazy datasource storage.
renderer
"canvas" | "worker"
"canvas"
"worker" paints off-thread via OffscreenCanvas, falling back to canvas. See Worker rendering.
workerUrl
string | URL
undefined
Usually not needed: bundlers such as Vite build the default worker. Without a bundler, pass a browser-fetchable module URL, for example "/sheetwrite/worker.js" after you copy the package dist/. See Worker rendering.
theme
Partial<Theme>
undefined
Overrides merged over DEFAULT_THEME and any --sheetwrite-* CSS vars. See Styling.
readOnly
boolean
false
When true, all mutating interactions (edit, clear, fill, paste, restyle) are disabled and the host gets aria-readonly="true".
hyperlinkActivation
"event-only" | "internal-navigation" | "disabled"
"event-only"
Activation never opens a browser URL. event-only emits a safe resolved target; internal-navigation also moves to stable internal destinations; disabled rejects every activation.
protectionResolver
ProtectionResolver
undefined
Host callback for protected local mutations; no resolver means deny. Client-side UX policy only, never server authorization.
mutationPolicy
"atomic" | "partial"
"atomic"
Reject the whole local transaction on a denied protected operation, or apply allowed operations and report denied ones.
transactionResourceLimits
Partial<TransactionResourceLimits>
undefined
Overrides the inclusive operation-count and encoded-byte ceilings for every atomic mutation.
renderers
Record<string, CellRenderer>
{}
Custom cell renderers registered up front; reference one by name via Column.renderer. See Custom cell renderers.
editors
Record<string, CellEditor>
{}
Host-owned cell editors registered up front; reference one by name via Column.editor. See Custom editors.
overscan
number
6
Row and visible-column positions painted on each viewport edge; 0 disables the buffer.
minColumns
number
workbook width
Minimum rendered/store column count. A spreadsheet also adds empty columns to fill the host width; a data-grid shows only its own columns unless you set minColumns.
config
GridConfig
undefined
Presence opts into the built-in toolbar. Omit it for no toolbar. See Toolbar and ribbon.
Spreadsheet and data-grid presentation
presentation: "spreadsheet" is the backward-compatible default. It paints and announces positional column headers (A, B, C, …). Use presentation: "data-grid" when the columns describe row-object fields:
The semantic header occupies the same header band as A/B/C; it does not consume row 0. These keep their zero-based data coordinates:
cell addresses, formulas, selections and row numbers
clipboard payloads and CSV/XLSX schema labels
mutation events and datasource ranges
Table exports use Column.header in both presentation modes. The data-first Sheetwrite components select "data-grid" automatically because every SimpleColumn requires a title.
Custom cell renderers
A CellRenderer paints or retains a DOM node for each cell in the rendered window. Register it in renderers or later with grid.defineCellRenderer(name, renderer). When dom is present, it owns the cell content. The canvas still paints the cell background, border, headers, and grid lines.
Creates an element when a cell enters the bounded rendered window.
update
Receives that same element after values, styles, theme, zoom, size, or scroll geometry change. Implement it to preserve focus and element-local state.
destroy
Runs immediately before the element leaves the window, is replaced by a newly registered renderer, or its grid is reset or destroyed.
A legacy renderer with only dom is recreated when its value, style, theme, or size changes, but not for a pure scroll.
DOM cells are clipped to the viewport and frozen pane that owns them. A merged range produces one node for its anchor, not one node per covered cell. Plain renderer output stays hidden from assistive technology because the compact ARIA mirror already exposes its cell value. To make a renderer explicitly interactive:
Return a native control, or add a non-negative tabindex.
Give it an accessible name.
Set element.style.pointerEvents = "auto".
Keyboard events from that control stay with the control instead of moving the grid.
With renderer: "worker", canvas hooks cannot cross the Worker boundary. dom, update, and destroy still run on the main thread in the retained overlay.
Framework adapters
Framework adapters classify every GridOptions field centrally:
Readiness includes the resulting generation and reset reason.
Framework adapters also accept wasmSource. Initialization is process-wide and first-source-wins:
Concurrent calls that use the same source share one attempt. A different source rejects until that attempt settles.
If the winning attempt succeeds, every still-mounted adapter becomes ready, even when its prop changed during the attempt.
A change to wasmSource after readiness warns and keeps the live grid, selection, edits, generation, and ready-event count unchanged.
A true initialization failure remains observable through onInitializationError, and a later source can retry it.
Edge cases and limits
Presentation is construction-bound. Changing it through a framework adapter replaces the grid with reason: "input-reset"; it does not rename columns or move data in place.
Pass data or datasource, not both.
readOnly keeps navigation and selection. Only mutating interactions stop.
protectionResolver is client-side UX policy. Your server must still authorize every submitted operation.
const grid: Gridconstgrid:Gridconstgrid:GridThe imperative core grid this controller owns.API reference →function createGrid(host: HTMLElement, opts: GridOptions): GridfunctioncreateGrid(host:HTMLElement,opts:GridOptions,):GridfunctioncreateGrid(host:HTMLElement,opts:GridOptions,):GridCreates and mounts an imperative Grid in the supplied host element.Exampleimport { createGrid, initSheetwrite } from"@sheetwrite/core";awaitinitSheetwrite();consthost= document.createElement("div");host.style.height ="400px";document.body.append(host);constgrid=createGrid(host, {workbook: {activeSheet: "sales",sheets: [{ id: "sales", name: "Sales", rowCount: 2,columns: [{ key: "amount", header: "Amount", type: "number", width: 120 }] }],},data: { rowCount: 2, columns: { amount: [12, 18] } },});grid.scrollToCell({ sheet: "sales", row: 1, col: 0 });// Call when the host view is removed.grid.destroy();See alsoGrid *See alsoGridOptionsAPI reference →const host: HTMLElementconsthost:HTMLElementconsthost:HTMLElementGridOptions.workbook: WorkbookinterfaceGridOptions {workbook:Workbook;}interfaceGridOptions {workbook:Workbook;}Live workbook schema adopted by the store and updated by document operations.API reference →GridOptions.data?: ColumnarData | undefinedinterfaceGridOptions {data?:ColumnarData|undefined;}interfaceGridOptions {data?:ColumnarData|undefined;}Eager column-major values loaded into workbook.activeSheet; use instead of datasource.API reference →GridOptions.presentation?: GridPresentation | undefinedinterfaceGridOptions {presentation?:GridPresentation|undefined;}interfaceGridOptions {presentation?:GridPresentation|undefined;}Header presentation. Spreadsheet mode (default) paints positional A/B/C labels; data-grid mode paints each column's semantic header. Cell addressing, row indices, clipboard values, formulas, and exports are unchanged in both modes.API reference →GridOptions.overscan?: number | undefinedinterfaceGridOptions {overscan?:number|undefined;}interfaceGridOptions {overscan?:number|undefined;}Extra row and visible-column positions painted on each viewport edge. Defaults to 6; use 0 to disable the buffer.API reference →function initSheetwrite(source?: BufferSource | URL | string | Request | WebAssembly.Module, engine?: SheetwriteEngine): Promise<void>functioninitSheetwrite(source?:BufferSource|URL|string|Request|WebAssembly.Module,engine?:SheetwriteEngine,):Promise<void>functioninitSheetwrite(source?:|BufferSource|URL|string|Request|WebAssembly.Module,engine?:SheetwriteEngine,):Promise<void>Load one WASM engine before createGrid. The default is @sheetwrite/wasm. Pass the @sheetwrite/formulas module as the second argument to select the full engine.Exampleimport { initSheetwrite } from"@sheetwrite/core";import*as formulas from"@sheetwrite/formulas";awaitinitSheetwrite(undefined, formulas);See also/docs/start/choose-an-engine/See alsocreateGridAPI reference →interface ColumnarDatainterfaceColumnarDatainterfaceColumnarDataEager column-oriented values used to initialize a sheet.API reference →interface WorkbookinterfaceWorkbookinterfaceWorkbookLive workbook schema containing ordered sheets and the active sheet ID.API reference →const host: HTMLElement | nullconsthost:HTMLElement|nullconsthost:HTMLElement|nullvar document: Documentvar document:Documentvar document:Documentwindow.document returns a reference to the document contained in the window. MDN ReferenceAPI reference →ParentNode.querySelector<HTMLElement>(selectors: string): HTMLElement | null (+4 overloads)ParentNode.querySelector<HTMLElement>(selectors: string): HTMLElement |null (+4 overloads)ParentNode.querySelector<HTMLElement>(selectors: string): HTMLElement |null (+4 overloads)Returns the first element that is a descendant of node that matches selectors. MDN Referenceinterface HTMLElementinterfaceHTMLElementinterfaceHTMLElementThe HTMLElement interface represents any HTML element. MDN Referencevar Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+2 overloads)var Error:ErrorConstructornew (message?:string, options?:ErrorOptions) =>Error (+2 overloads)var Error:ErrorConstructornew (message?:string, options?:ErrorOptions) =>Error (+2 overloads)ElementCSSInlineStyle.style: CSSStyleDeclarationinterfaceElementCSSInlineStyle {style:CSSStyleDeclaration;}interfaceElementCSSInlineStyle {style:CSSStyleDeclaration;}MDN ReferenceAPI reference →CSSStyleDeclaration.height: stringinterfaceCSSStyleDeclaration {height:string;}interfaceCSSStyleDeclaration {height:string;}MDN ReferenceAPI reference →const workbook: Workbookconstworkbook:Workbookconstworkbook:WorkbookLive workbook schema adopted by the store and updated by document operations.API reference →Workbook.activeSheet: stringinterfaceWorkbook {activeSheet:string;}interfaceWorkbook {activeSheet:string;}Active sheet ID and initial tab presented when the grid is created.API reference →Workbook.sheets: Sheet[]interfaceWorkbook {sheets:Sheet[];}interfaceWorkbook {sheets:Sheet[];}Sheets in display/tab order.API reference →Sheet.id: stringinterfaceSheet {id:string;}interfaceSheet {id:string;}Stable identifier, unique within the workbook and used by every cell address.API reference →Sheet.name: stringinterfaceSheet {name:string;}interfaceSheet {name:string;}User-facing sheet name shown in tabs and workbook exports.API reference →Sheet.rowCount: numberinterfaceSheet {rowCount:number;}interfaceSheet {rowCount:number;}Row count for both in-memory and datasource-backed sheets.API reference →Sheet.columns: Column[]interfaceSheet {columns:Column[];}interfaceSheet {columns:Column[];}Ordered schema; array positions are the zero-based column coordinates.API reference →Column.key: stringinterfaceColumn {key:string;}interfaceColumn {key:string;}Non-empty key, unique within the sheet, used to map input and datasource values.API reference →Column.header: stringinterfaceColumn {header:string;}interfaceColumn {header:string;}Schema label used by table exports and data-grid presentation headers.API reference →Column.width: numberinterfaceColumn {width:number;}interfaceColumn {width:number;}Unzoomed column width in CSS pixels.API reference →Column.type: CellFormatinterfaceColumn {type:CellFormat;}interfaceColumn {type:CellFormat;}Controls cell input parsing and default value formatting for this column.API reference →const data: ColumnarDataconstdata:ColumnarDataconstdata:ColumnarDataEager column-major values loaded into workbook.activeSheet; use instead of datasource.API reference →ColumnarData.rowCount: numberinterfaceColumnarData {rowCount:number;}interfaceColumnarData {rowCount:number;}Row count for both in-memory and datasource-backed sheets.API reference →ColumnarData.columns: Record<string, ArrayLike<CellScalar | CellValue>>interfaceColumnarData {columns:Record<string, ArrayLike<CellScalar|CellValue>>;}interfaceColumnarData {columns:Record<string,ArrayLike<CellScalar|CellValue>>;}Exact column runs represented by every returned row.API reference →name: string[]let name:string[]let name:string[]User-facing caption.API reference →status: string[]let status:string[]let status:string[]var console: Consolevar console:Consolevar console:ConsoleConsole.log(...data: any[]): void (+1 overload)Console.log(...data: any[]): void (+1 overload)Console.log(...data: any[]): void (+1 overload)The console.log() static method outputs a message to the console. MDN ReferenceGrid.store: StoreinterfaceGrid {store:Store;}interfaceGrid {store:Store;}Store.getCell(addr: CellAddress): ResolvedCellStore.getCell(addr: CellAddress): ResolvedCellStore.getCell(addr: CellAddress): ResolvedCellSingle-cell read for interactions, API reads, and tests. NOT for the render hot path — renderers use getVisibleWindow.API reference →CellAddress.sheet: stringinterfaceCellAddress {sheet:string;}interfaceCellAddress {sheet:string;}Sheet identity used by the simple data-first adapter. Defaults to sheet1.API reference →CellAddress.row: numberinterfaceCellAddress {row:number;}interfaceCellAddress {row:number;}0-based row of the cell that holds the top-left corner.API reference →CellAddress.col: numberinterfaceCellAddress {col:number;}interfaceCellAddress {col:number;}0-based column of the cell that holds the top-left corner.API reference →ResolvedCell.resolved: CellScalarinterfaceResolvedCell {resolved:CellScalar;}interfaceResolvedCell {resolved:CellScalar;}interface GridOptionsinterfaceGridOptionsinterfaceGridOptionsWorkbook, data, rendering, policy, and built-in UI options used to create a Grid.Exampleimporttype { GridOptions } from"@sheetwrite/core";constoptions:GridOptions= {workbook: { activeSheet: "sheet1", sheets: [{ id: "sheet1", name: "Sheet 1", rowCount: 1,columns: [{ key: "name", header: "Name", type: "text", width: 120 }] },] },data: { rowCount: 1, columns: { name: ["Ada"] } },config: { toolbar: true, contextMenu: true, keyboard: true },};See alsocreateGrid *See alsoGridConfigAPI reference →interface GridinterfaceGridinterfaceGridImperative grid handle for document commands, events, rendering, and teardown.Exampleimporttype { Grid } from"@sheetwrite/core";functionupdateTotal(grid:Grid) {constsheet= grid.getActiveSheet();constresult= grid.applyTransaction({patches: [{ op: "set", addr: { sheet, row: 0, col: 0 }, value: { kind: "literal", value: 42 } }],});if (result.status ==="applied") grid.scrollToCell({ sheet, row: 0, col: 0 });return grid.aggregate(0, "sum");}See alsocreateGrid *See alsoGrid.applyTransactionAPI reference →const people: readonly Record<string, CellScalar>[]constpeople:readonlyRecord<string, CellScalar>[]constpeople:readonlyRecord<string,CellScalar>[]API reference →ReadonlyArray<Record<string, CellScalar>>.length: numberReadonlyArray<Record<string, CellScalar>>.length: numberReadonlyArray<Record<string, CellScalar>>.length: numberGets the length of the array. This is a number one higher than the highest element defined in an array.API reference →interface CellRenderer
interface CellRendererinterfaceCellRendererinterfaceCellRendererinterfaceCellRendererinterfaceCellRendererCustom cell renderer hooks for the main-thread canvas or retained DOM overlay.API reference →CellRenderer.canvas?(ctx: CanvasRenderingContext2D, c: CellPaintContext): voidCellRenderer.canvas?(ctx:CanvasRenderingContext2D, c:CellPaintContext):voidCellRenderer.canvas?(ctx:CanvasRenderingContext2D, c:CellPaintContext):voidinterface CanvasRenderingContext2DinterfaceCanvasRenderingContext2DinterfaceCanvasRenderingContext2DThe CanvasRenderingContext2D interface, part of the Canvas API, provides the 2D rendering context for the drawing surface of a canvas element. MDN Referenceinterface CellPaintContextinterfaceCellPaintContextinterfaceCellPaintContextRead-only cell value and screen geometry supplied to a custom renderer.API reference →CellRenderer.dom?(c: CellPaintContext): HTMLElementCellRenderer.dom?(c:CellPaintContext):HTMLElementCellRenderer.dom?(c:CellPaintContext):HTMLElementCreates a fresh, detached element uniquely owned by one retained DOM cell.API reference →CellRenderer.update?(element: HTMLElement, c: CellPaintContext): voidCellRenderer.update?(element:HTMLElement, c:CellPaintContext):voidCellRenderer.update?(element:HTMLElement, c:CellPaintContext):voidUpdates a retained element after its value, style, theme, or geometry changes.API reference →element: HTMLElementlet element:HTMLElementlet element:HTMLElementThe shell's root element (already appended to the mount host).API reference →CellRenderer.destroy?(element: HTMLElement): voidCellRenderer.destroy?(element:HTMLElement):voidCellRenderer.destroy?(element:HTMLElement):voidRuns immediately before a retained element is removed or replaced.API reference →