October 2026 - Data Grid Performance
Data Grid stays smooth at 100k rows, with keyboard row inserts, better copying, and a new onRowAdd signature.
Data Grid now stays smooth at 100k rows. It virtualizes columns as well as rows, shows lightweight preview cells while you scroll, and reuses row elements instead of remounting them. Sorting, searching and filtering cache their work, so large grids respond faster as you type.
- Insert rows from the keyboard. Shift + Enter on a cell inserts a row below it.
- Cell menu from the keyboard. Shift + F10 opens the focused cell's context menu.
- Copying. Ctrl / Cmd + C copies checked rows, and values with tabs, line breaks or a leading quote are quoted, so multi-line text pastes into one cell.
- Focus. Deleting rows moves keyboard focus to the next row's first data cell, and
onCellFocuslets you follow it. - Editing. Text and URL cells scroll to the caret when editing starts.
- Row action labels.
getDataGridActionsColumntakesgetAriaLabel(row)to name each row's menu trigger, likegetDataTableActionsColumn. - Custom renderers. A column's own
cellandheaderrender through TanStack Table'sflexRender, so renderers that use hooks,memoorforwardRefwork.
Migrating
This release has breaking changes. Reinstall all Data Grid files together, because the components, hook, and lib files depend on each other. It adds a new file, data-grid-cell-preview.tsx.
onRowAddreceiveseventDetails. It used to receive the click event. Now it gets one object with areason:"add-row-press"for the add row button,"insert-below"for Shift + Enter (with theafterRowIdto insert after), or"paste"when a paste needs more rows. CalleventDetails.cancel()to skip focusing the new row.onScrollToCellis nowonCellScroll. This only matters if you set the grid's table options yourself.flexRendermoved. It's no longer exported fromlib/data-grid-utils. Import it from@tanstack/react-tableinstead.- Columns with their own
cellrender it. A column with acellrenderer and nometa.cell.variantnow shows that renderer, read-only, instead of the default text editor. Addmeta.cell.variantto keep it editable.
const { table, ...dataGridProps } = useDataGrid({
data,
columns,
onDataChange: setData,
onRowAdd: (eventDetails) => {
const row = { id: crypto.randomUUID() };
const afterRowId =
eventDetails.reason === "insert-below"
? eventDetails.afterRowId
: undefined;
setData((prev) => {
const index = prev.findIndex((item) => item.id === afterRowId);
return index === -1
? [...prev, row]
: [...prev.slice(0, index + 1), row, ...prev.slice(index + 1)];
});
return { rowId: row.id, columnId: "name" };
},
});