A B C D E 1 Notebook 3 8 $24.00 2 Pen 5 2 $10.00 3
Result: A1:D2 after the host returns the two product rows
For this result, the workbook columns are label, quantity, price, and total, in that order. The host endpoint returns [{ "label": "Notebook", "quantity": 3, "price": 8 }, { "label": "Pen", "quantity": 5, "price": 2 }]. The adapter below supplies the formula and bold currency style for each total; D1 evaluates =B1*C1.
Try it live: Engine showcase — jump between rows and inspect the datasource request and arrival events. Its datasource is local to the page, not a remote server.
Start with the host and initialization in Your first grid , replacing eager data with datasource. A DataSource loads cancellable pages for the visible window, so the grid does not need the whole sheet in memory. The HTTP endpoint and its backing data remain your responsibility.
Datasource adapter setup — requires your server endpoint
import type { RowData } from "@sheetwrite/core" ; const response = await fetch (
`/sheets/${ encodeURIComponent ( sheet ) }?start=${ start }&end=${ end }` , if ( ! response . ok ) throw new Error ( `Datasource request failed: ${ response . status }` );
const records = ( await response . json ()) as ApiRow [];
quantity : record . quantity ,
value : { kind: "formula" , src : `=B${ row }*C${ row }` }, // Return exactly the column runs the grid asked for.
return Object . fromEntries (
The grid requests rows only for the visible window. The endpoint must return records for the requested row interval; this example selects the requested column runs before returning each page to the grid.
Requests and pages
The cancellable request API owns one visible-window generation. Pages can carry authoritative formula source and style, not only resolved scalars.
Field Where Meaning capabilities.columnsDataSource"windowed" loads only the requested column runs. "full-width" loads every column; it does not scale horizontally.start / endrequest Inclusive first row and exclusive end row. columnsrequest and page Exact visible, frozen, or prefetched column runs. Each run has start, exclusive end, and the stable column keys. signalrequest Aborted when the request is no longer needed. Stop work when it aborts. revisionrequest and page The request carries a number; a page may return a string or number revision. rowspage Each value is a scalar, a CellValue object, or a { value: CellValue, style?: CellStyle } wrapper.
Storage
datasourceStorage fieldDefault Effect mode"dense""paged" allocates power-of-two row chunks only for loaded or locally edited areas.chunkRows4,096 Paged row chunk size, normalized to a power of two. cacheBytes32 MiB Per-sheet budget for clean cached chunks. Dirty chunks remain pinned until acknowledgement. dirtyCellLimit1,000,000 Maximum sparse local edits retained outside the clean page cache.
Full-sheet queries and exports report incomplete data until all required pages are loaded. Store.queryCapability(sheet) and getCellLoadState(addr) expose that state. Default chunk and cache values and eviction behavior are also listed in Compatibility and limits .
A visible formula can read cells outside the visible window. For example, a variance column can read a plan column far to the right. The grid asks the engine which same-sheet cells the painted formulas read, also through other formulas, and requests those cells with the window. This includes frozen bands, overscan, and merge anchors reached by the paint plan. The formula then resolves instead of staying #LOADING!.
One shared 32,768-cell budget bounds dependency loading across these roots. A whole-column read does not load the full column in one window.
The painted cells and their bounded dependency closure stay protected from clean-cache eviction while visible.
Bulk reads such as exports and search use separate, transient protection. They do not replace the viewport's pins.
Reads from other sheets are not loaded this way. Return those values from the datasource, or keep that sheet dense.
Edge cases and limits
Hydrated formulas, references, and styles do not emit user change events.
A short page marks only the returned rows loaded.
A malformed range emits datasource-error and stays retryable.
Resetting or destroying the grid aborts outstanding requests.
A late page never overwrites a cell edited after that request began.
See also
function createGrid(host: HTMLElement, opts: GridOptions): Grid function createGrid (
host : HTMLElement ,
opts : GridOptions ,
) : Grid function createGrid (
host : HTMLElement ,
opts : GridOptions ,
) : Grid Creates and mounts an imperative Grid in the supplied host element. Example import { createGrid, initSheetwrite } from "@sheetwrite/core" ;
await initSheetwrite ();
const host = document. createElement ( "div" );
host.style.height = "400px" ;
document.body. append (host);
const grid = 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 also Grid * See also GridOptions API reference → const host: HTMLElement const host : HTMLElement const host : HTMLElement GridOptions.workbook: Workbook interface GridOptions {
workbook : Workbook ;
} interface GridOptions {
workbook : Workbook ;
} Live workbook schema adopted by the store and updated by document operations. API reference → GridOptions.datasource?: DataSource | undefined interface GridOptions {
datasource ?: DataSource | undefined ;
} interface GridOptions {
datasource ?:
DataSource | undefined ;
} Lazy row provider requested for visible windows; use instead of eager data. API reference → GridOptions.datasourceStorage?: DataSourceStorageOptions | undefined interface GridOptions {
datasourceStorage ?: DataSourceStorageOptions | undefined ;
} interface GridOptions {
datasourceStorage ?:
| DataSourceStorageOptions
| undefined ;
} Allocation and cache policy for datasource-backed cell storage. API reference → DataSourceStorageOptions.mode?: "dense" | "paged" | undefined interface DataSourceStorageOptions {
mode ?: "dense" | "paged" | undefined ;
} interface DataSourceStorageOptions {
mode ?:
"dense" | "paged" | undefined ;
} Storage engine. Dense is the default. API reference → type RowData = {
[x: string]: DataCell;
} type RowData = {
[ x : string ] : DataCell ;
}; type RowData = {
[ x : string ] : DataCell ;
}; Object-shaped datasource row keyed by workbook column keys. API reference → ApiRow.label: string interface ApiRow {
label : string ;
} interface ApiRow {
label : string ;
} Menu row text. Defaults per action. API reference → ApiRow.quantity: number interface ApiRow {
quantity : number ;
} interface ApiRow {
quantity : number ;
} ApiRow.price: number interface ApiRow {
price : number ;
} interface ApiRow {
price : number ;
} const datasource: DataSource const datasource : DataSource const datasource : DataSource Lazy row provider requested for visible windows; use instead of eager data. API reference → interface DataSource interface DataSource interface DataSource Host callback that asynchronously loads cancellable rectangular pages. Example import type { DataSource, RowData } from "@sheetwrite/core" ;
const rows : RowData [] = [{ amount: 12 }, { amount: 18 }];
const datasource : DataSource = {
capabilities: { protocol: 2 , columns: "windowed" },
async getRows ( request ) {
request.signal. throwIfAborted ();
return {
protocol: 2 , start: request.start, columns: request.columns,
rows: rows. slice (request.start, request.end). map (( row ) =>
Object. fromEntries (request.columns. flatMap (( band ) =>
band.keys. map (( key ) => [key, row[key] ?? null ])))),
};
},
}; See also GridOptions.datasource * See also DataSourceRequest API reference → DataSource.capabilities: DataSourceCapabilities interface DataSource {
capabilities : DataSourceCapabilities ;
} interface DataSource {
capabilities : DataSourceCapabilities ;
} DataSourceCapabilities.protocol: 2 interface DataSourceCapabilities {
protocol : 2 ;
} interface DataSourceCapabilities {
protocol : 2 ;
} Paging contract version. API reference → DataSourceCapabilities.columns: "windowed" | "full-width" interface DataSourceCapabilities {
columns : "windowed" | "full-width" ;
} interface DataSourceCapabilities {
columns :
"windowed" | "full-width" ;
} Exact column runs represented by every returned row. API reference → DataSource.getRows(request: DataSourceRequest): Promise<DataSourcePage> DataSource. getRows (request: DataSourceRequest): Promise < DataSourcePage > DataSource. getRows (request: DataSourceRequest): Promise < DataSourcePage > Loads the requested rows and columns; implementations should stop work when its signal aborts. API reference → sheet: string let sheet : string let sheet : string Sheet identity used by the simple data-first adapter. Defaults to sheet1. API reference → start: number let start : number let start : number Inclusive row index. API reference → end: number let end : number let end : number Exclusive row index. API reference → columns: readonly DataSourceColumnBand[] let columns : readonly DataSourceColumnBand [] let columns : readonly DataSourceColumnBand [] Exact visible, frozen, or prefetched column runs required by the Grid. API reference → signal: AbortSignal let signal : AbortSignal let signal : AbortSignal Abort between bounded encode chunks or store windows. API reference → revision: number let revision : number let revision : number const response: Response const response : Response const response : Response function fetch(input: string | URL | Request, init?: RequestInit): Promise<Response> (+2 overloads)
namespace fetch function fetch ( input : string | URL | Request , init ?: RequestInit ) : Promise < Response > (+ 2 overloads )
namespace fetch function fetch ( input : string | URL | Request , init ?: RequestInit ) : Promise < Response > (+ 2 overloads )
namespace fetch MDN Reference function encodeURIComponent(uriComponent: string | number | boolean): string function encodeURIComponent (
uriComponent : string | number | boolean ,
) : string function encodeURIComponent (
uriComponent :
string | number | boolean ,
) : string Encodes a text string as a valid component of a Uniform Resource Identifier (URI). @param uriComponent A value representing an unencoded URI component.RequestInit.signal?: AbortSignal | null | undefined interface RequestInit {
signal ?: AbortSignal | null | undefined ;
} interface RequestInit {
signal ?:
| AbortSignal
| null
| undefined ;
} An AbortSignal to set request's signal. API reference → Response.ok: boolean interface Response {
ok : boolean ;
} interface Response {
ok : boolean ;
} The ok read-only property of the Response interface contains a Boolean stating whether the response was successful (status in the range 200-299) or not. MDN Reference var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+2 overloads) var Error : ErrorConstructor
new ( message ?: string , options ?: ErrorOptions ) => Error ( + 2 overloads) var Error : ErrorConstructor
new ( message ?: string , options ?: ErrorOptions ) => Error ( + 2 overloads) Response.status: number interface Response {
status : number ;
} interface Response {
status : number ;
} The status read-only property of the Response interface contains the HTTP status codes of the response. MDN Reference const records: ApiRow[] const records : ApiRow [] const records : ApiRow [] Body.json(): Promise<any> Body. json (): Promise < any > Body. json (): Promise < any > MDN Reference interface ApiRow interface ApiRow interface ApiRow DataSourcePage.protocol: 2 interface DataSourcePage {
protocol : 2 ;
} interface DataSourcePage {
protocol : 2 ;
} Paging contract version. API reference → DataSourcePage.start: number interface DataSourcePage {
start : number ;
} interface DataSourcePage {
start : number ;
} Inclusive row index of the first returned row. API reference → DataSourcePage.columns: readonly DataSourceColumnBand[] interface DataSourcePage {
columns : readonly DataSourceColumnBand [];
} interface DataSourcePage {
columns : readonly DataSourceColumnBand [];
} Exact column runs represented by every returned row. API reference → DataSourcePage.revision?: string | number | undefined interface DataSourcePage {
revision ?: string | number | undefined ;
} interface DataSourcePage {
revision ?:
string | number | undefined ;
} API reference → Response.headers: Headers interface Response {
headers : Headers ;
} interface Response {
headers : Headers ;
} The headers read-only property of the with the response. MDN Reference Headers.get(name: string): string | null Headers. get (name: string): string | null Headers. get (name: string): string | null The get() method of the Headers interface returns a byte string of all the values of a header within a Headers object with a given name. MDN Reference API reference → DataSourcePage.rows: RowData[] interface DataSourcePage {
rows : RowData [];
} interface DataSourcePage {
rows : RowData [];
} Source field indices that group the output rows, outermost first. API reference → Array<ApiRow>.map<{
[k: string]: string | number | boolean | {
kind: "literal";
value: CellScalar;
} | {
kind: "ref";
target: CellAddress;
} | {
kind: "formula";
src: string;
} | {
value: CellValue;
style?: CellStyle;
} | null;
}>(callbackfn: (value: ApiRow, index: number, array: ApiRow[]) => {
[k: string]: string | number | boolean | {
kind: "literal";
value: CellScalar;
} | {
kind: "ref";
target: CellAddress;
} | {
kind: "formula";
src: string;
} | {
value: CellValue;
style?: CellStyle;
} | null;
}, thisArg?: any): {
[k: string]: string | number | boolean | {
kind: "literal";
value: CellScalar;
} | {
kind: "ref";
target: CellAddress;
} | {
kind: "formula";
src: string;
} | {
value: CellValue;
style?: CellStyle;
} | null;
}[] Array < ApiRow > . map <{
[ k : string ] : string | number | boolean | {
kind : "literal" ;
value : CellScalar ;
} | {
kind : "ref" ;
target : CellAddress ;
} | {
kind : "formula" ;
src : string ;
} | {
value : CellValue ;
style ?: CellStyle ;
} | null ;
}>( callbackfn : ( value : ApiRow , index : number , array : ApiRow []) => {
[ k : string ] : string | number | boolean | {
kind : "literal" ;
value : CellScalar ;
} | {
kind : "ref" ;
target : CellAddress ;
} | {
kind : "formula" ;
src : string ;
} | {
value : CellValue ;
style ?: CellStyle ;
} | null ;
}, thisArg ?: any ) : {
[ k : string ] : string | number | boolean | {
kind : "literal" ;
value : CellScalar ;
} | {
kind : "ref" ;
target : CellAddress ;
} | {
kind : "formula" ;
src : string ;
} | {
value : CellValue ;
style ?: CellStyle ;
} | null ;
}[] Array < ApiRow > . map <{
[ k : string ] : string | number | boolean | {
kind : "literal" ;
value : CellScalar ;
} | {
kind : "ref" ;
target : CellAddress ;
} | {
kind : "formula" ;
src : string ;
} | {
value : CellValue ;
style ?: CellStyle ;
} | null ;
}>( callbackfn : ( value : ApiRow , index : number , array : ApiRow []) => {
[ k : string ] : string | number | boolean | {
kind : "literal" ;
value : CellScalar ;
} | {
kind : "ref" ;
target : CellAddress ;
} | {
kind : "formula" ;
src : string ;
} | {
value : CellValue ;
style ?: CellStyle ;
} | null ;
}, thisArg ?: any ) : {
[ k : string ] : string | number | boolean | {
kind : "literal" ;
value : CellScalar ;
} | {
kind : "ref" ;
target : CellAddress ;
} | {
kind : "formula" ;
src : string ;
} | {
value : CellValue ;
style ?: CellStyle ;
} | null ;
}[] Calls a defined callback function on each element of an array, and returns an array that contains the results. @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.@param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.record: ApiRow let record : ApiRow let record : ApiRow index: number let index : number let index : number Source field index, as used by rows, columns, values and filters. API reference → const row: number const row : number const row : number 0-based row of the cell that holds the top-left corner. API reference → label: string let label : string let label : string Menu row text. Defaults per action. API reference → quantity: number let quantity : number let quantity : number price: number let price : number let price : number total: {
value: {
kind: "formula";
src: string;
};
style: {
numberFormat: string;
bold: true;
};
} let total : {
value : {
kind : "formula" ;
src : string ;
};
style : {
numberFormat : string ;
bold : true ;
};
} let total : {
value : {
kind : "formula" ;
src : string ;
};
style : {
numberFormat : string ;
bold : true ;
};
} value: {
kind: "formula";
src: string;
} let value : {
kind : "formula" ;
src : string ;
} let value : {
kind : "formula" ;
src : string ;
} src: string let src : string let src : string style?: CellStyle | undefined style ?: CellStyle | undefined style ?: CellStyle | undefined Optional override merged over the deterministic blue/underline link style. API reference → CellStyle.numberFormat?: string | undefined interface CellStyle {
numberFormat ?: string | undefined ;
} interface CellStyle {
numberFormat ?:
string | undefined ;
} Excel number-format code for this cell, e.g. "0.00%". Overrides the column's numberFormat; at most 255 characters. API reference → CellStyle.bold?: boolean | undefined interface CellStyle {
bold ?: boolean | undefined ;
} interface CellStyle {
bold ?: boolean | undefined ;
} Uses the bold variant of the theme font. API reference → var Object: ObjectConstructor var Object : ObjectConstructor var Object : ObjectConstructor Provides functionality common to all JavaScript objects. ObjectConstructor.fromEntries<string | number | boolean | {
kind: "literal";
value: CellScalar;
} | {
kind: "ref";
target: CellAddress;
} | {
kind: "formula";
src: string;
} | {
value: CellValue;
style?: CellStyle;
} | null>(entries: Iterable<readonly [PropertyKey, string | number | boolean | {
kind: "literal";
value: CellScalar;
} | {
kind: "ref";
target: CellAddress;
} | {
kind: "formula";
src: string;
} | {
value: CellValue;
style?: CellStyle;
} | null]>): {
[k: string]: string | number | boolean | {
kind: "literal";
value: CellScalar;
} | {
...;
} | {
...;
} | {
...;
} | null;
} (+1 overload) ObjectConstructor.fromEntries < string | number | boolean | {
kind : "literal" ;
value : CellScalar;
} | {
kind : "ref" ;
target : CellAddress;
} | {
kind : "formula" ;
src : string;
} | {
value : CellValue;
style ?: CellStyle;
} | null > ( entries : Iterable < readonly [ PropertyKey , string | number | boolean | {
kind : "literal" ;
value : CellScalar ;
} | {
kind : "ref" ;
target : CellAddress ;
} | {
kind : "formula" ;
src : string ;
} | {
value : CellValue ;
style ?: CellStyle ;
} | null ]>) : {
[ k : string ] : string | number | boolean | {
kind : "literal" ;
value : CellScalar ;
} | {
... ;
} | {
... ;
} | {
... ;
} | null ;
} (+ 1 overload ) ObjectConstructor.fromEntries < string | number | boolean | {
kind : "literal" ;
value : CellScalar;
} | {
kind : "ref" ;
target : CellAddress;
} | {
kind : "formula" ;
src : string;
} | {
value : CellValue;
style ?: CellStyle;
} | null > ( entries : Iterable < readonly [ PropertyKey , string | number | boolean | {
kind : "literal" ;
value : CellScalar ;
} | {
kind : "ref" ;
target : CellAddress ;
} | {
kind : "formula" ;
src : string ;
} | {
value : CellValue ;
style ?: CellStyle ;
} | null ]>) : {
[ k : string ] : string | number | boolean | {
kind : "literal" ;
value : CellScalar ;
} | {
... ;
} | {
... ;
} | {
... ;
} | null ;
} (+ 1 overload ) Returns an object created by key-value entries for properties and methods @param entries An iterable object that contains key-value entries for properties and methods.ReadonlyArray<DataSourceColumnBand>.flatMap<[string, string | number | boolean | {
kind: "literal";
value: CellScalar;
} | {
kind: "ref";
target: CellAddress;
} | {
kind: "formula";
src: string;
} | {
value: CellValue;
style?: CellStyle;
} | null], undefined>(callback: (this: undefined, value: DataSourceColumnBand, index: number, array: DataSourceColumnBand[]) => [string, string | number | boolean | {
kind: "literal";
value: CellScalar;
} | {
kind: "ref";
target: CellAddress;
} | {
kind: "formula";
src: string;
} | {
value: CellValue;
style?: CellStyle;
} | null] | readonly [...][], thisArg?: undefined): [...][] ReadonlyArray < DataSourceColumnBand > .flatMap < [string, string | number | boolean | {
kind: "literal" ;
value: CellScalar;
} | {
kind: "ref" ;
target: CellAddress;
} | {
kind: "formula" ;
src: string;
} | {
value: CellValue;
style ?: CellStyle;
} | null ], undefined > ( callback : ( this : undefined , value : DataSourceColumnBand , index : number , array : DataSourceColumnBand []) => [ string , string | number | boolean | {
kind : "literal" ;
value : CellScalar ;
} | {
kind : "ref" ;
target : CellAddress ;
} | {
kind : "formula" ;
src : string ;
} | {
value : CellValue ;
style ?: CellStyle ;
} | null ] | readonly [ ... ][], thisArg ?: undefined ) : [ ... ][] ReadonlyArray < DataSourceColumnBand > .flatMap < [string, string | number | boolean | {
kind: "literal" ;
value: CellScalar;
} | {
kind: "ref" ;
target: CellAddress;
} | {
kind: "formula" ;
src: string;
} | {
value: CellValue;
style ?: CellStyle;
} | null ], undefined > ( callback : ( this : undefined , value : DataSourceColumnBand , index : number , array : DataSourceColumnBand []) => [ string , string | number | boolean | {
kind : "literal" ;
value : CellScalar ;
} | {
kind : "ref" ;
target : CellAddress ;
} | {
kind : "formula" ;
src : string ;
} | {
value : CellValue ;
style ?: CellStyle ;
} | null ] | readonly [ ... ][], thisArg ?: undefined ) : [ ... ][] Calls a defined callback function on each element of an array. Then, flattens the result into a new array. This is identical to a map followed by flat with depth 1. @param callback A function that accepts up to three arguments. The flatMap method calls the callback function one time for each element in the array.@param thisArg An object to which the this keyword can refer in the callback function. If thisArg is omitted, undefined is used as the this value.band: DataSourceColumnBand let band : DataSourceColumnBand let band : DataSourceColumnBand API reference → DataSourceColumnBand.keys: readonly string[] interface DataSourceColumnBand {
keys : readonly string [];
} interface DataSourceColumnBand {
keys : readonly string [];
} Stable workbook column keys for every index in [start, end). API reference → ReadonlyArray<string>.map<[string, string | number | boolean | {
kind: "literal";
value: CellScalar;
} | {
kind: "ref";
target: CellAddress;
} | {
kind: "formula";
src: string;
} | {
value: CellValue;
style?: CellStyle;
} | null]>(callbackfn: (value: string, index: number, array: readonly string[]) => [string, string | number | boolean | {
kind: "literal";
value: CellScalar;
} | {
kind: "ref";
target: CellAddress;
} | {
kind: "formula";
src: string;
} | {
value: CellValue;
style?: CellStyle;
} | null], thisArg?: any): [string, string | number | boolean | ... 4 more ... | null][] ReadonlyArray < string > .map < [string, string | number | boolean | {
kind: "literal" ;
value: CellScalar;
} | {
kind: "ref" ;
target: CellAddress;
} | {
kind: "formula" ;
src: string;
} | {
value: CellValue;
style ?: CellStyle;
} | null ] > ( callbackfn : ( value : string , index : number , array : readonly string []) => [ string , string | number | boolean | {
kind : "literal" ;
value : CellScalar ;
} | {
kind : "ref" ;
target : CellAddress ;
} | {
kind : "formula" ;
src : string ;
} | {
value : CellValue ;
style ?: CellStyle ;
} | null ], thisArg ?: any ) : [ string , string | number | boolean | ... 4 more ... | null ][] ReadonlyArray < string > .map < [string, string | number | boolean | {
kind: "literal" ;
value: CellScalar;
} | {
kind: "ref" ;
target: CellAddress;
} | {
kind: "formula" ;
src: string;
} | {
value: CellValue;
style ?: CellStyle;
} | null ] > ( callbackfn : ( value : string , index : number , array : readonly string []) => [ string , string | number | boolean | {
kind : "literal" ;
value : CellScalar ;
} | {
kind : "ref" ;
target : CellAddress ;
} | {
kind : "formula" ;
src : string ;
} | {
value : CellValue ;
style ?: CellStyle ;
} | null ], thisArg ?: any ) : [ string , string | number | boolean | ... 4 more ... | null ][] Calls a defined callback function on each element of an array, and returns an array that contains the results. @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.@param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.key: string let key : string let key : string Non-empty key, unique within the sheet, used to map input and datasource values. API reference → const cells: RowData const cells : RowData const cells : RowData API reference →