React data grid library

React data grid library for spreadsheet-grade apps

Ace Grid is built for React teams that need a real data-grid surface: editable cells, virtualized rows and columns, pinned regions, filtering, theming, CSV workflows, and a path into spreadsheet, enterprise, and AI workflows.

Install Ace Grid Open Core API

A data grid owns repeated interaction

A React data grid is justified when users edit cells, select records, navigate by keyboard, resize or pin columns, filter repeatedly, and work with more data than a simple table should mount. For a small read-only list, semantic HTML or a headless table is usually simpler.

Understand the Core contract

React uses Grid from @ace-grid/core with GridRow and GridColumn data contracts. The application supplies stable row IDs, typed cell values, a bounded layout height, and change handling. Core includes editing, selection, sorting, filtering, pagination, search, pinning, resizing, virtualization, CSV I/O, theming, and schema-aware state helpers under MIT.

Test integration, not only the demo

Verify TypeScript contracts, controlled row updates, validation ownership, custom cell rendering, focus behavior, loading and empty states, accessibility labels, bundle impact, and framework support. Ace Grid also publishes wrappers for Web Components, Angular, Vue, and Svelte.

Define the row and column contracts

A production grid needs stable row IDs, explicit column keys, predictable value types, and controlled update behavior. Stable identity is necessary for editing, selection, virtualization, and server synchronization. Columns should describe sorting, filtering, editing, formatting, width, and custom rendering without forcing the rest of the application to understand DOM details. Treat these contracts as application interfaces and test them with TypeScript rather than passing loosely shaped objects through the grid.

Decide who owns state

List which state belongs to the grid and which must be controlled by the application. Rows, server mutations, permissions, and authoritative validation normally remain application concerns. Sorting, filtering, selection, pagination, and column state may be controlled when they must synchronize with URLs, saved views, or other components. Avoid controlling every property without a reason because unnecessary synchronization increases render work and makes interaction harder to debug.

Design editing as a data transaction

Cell editing is not complete when an input appears. Define parsing, immediate validation, commit and cancel behavior, optimistic updates, backend rejection, row-version conflicts, dirty state, and retry. Core exposes editable columns, parsers, validators, editors, and onCellChange. The application still decides when a change becomes authoritative. Use Pro when the workflow needs deeper validation, formulas, or spreadsheet features rather than overloading basic cell callbacks.

Verify accessibility and keyboard behavior

Test the grid as an interactive widget, not only as a visual table. Confirm the accessible name, focus entry, arrow-key movement, edit mode, selection announcements, menus, and behavior at pinned or virtualized boundaries. Use representative custom cells because interactive controls inside a cell can change keyboard expectations. Automated checks help, but task-based testing with keyboard and screen-reader workflows is necessary for a grid used repeatedly by business users.

Measure performance with the real workload

Row count alone does not predict performance. Column count, custom renderers, cell formatting, row height, controlled state, client transformations, and browser hardware all matter. Benchmark the expected workflow: initial usable render, fast scrolling, edit start, filtering, resizing, and memory. Enable row, horizontal, or cell-content virtualization according to measured cost. For remote datasets, decide separately whether infinite loading or an Enterprise server row model is required.

Plan the package boundary

Start with @ace-grid/core when its MIT-licensed surface covers the product. Add Pro only when spreadsheet workflows create value, and Enterprise only when server-backed or analytical capabilities are required. This keeps procurement aligned with actual behavior and makes architecture easier to explain. Review package imports, license initialization, framework wrappers, and deployment requirements before implementation so the prototype uses the same boundary intended for production.

Design loading, empty, and failure states

A production grid must explain whether data is loading, genuinely empty, partially available, stale, or unavailable. Preserve column context when possible and avoid replacing the entire work surface with an unrelated spinner. For remote data, expose retry and cancellation behavior. For edits, attach errors to the affected row or cell. These states influence user trust more than a perfect demonstration with immediate local data.

Evaluate theming and custom rendering

Recreate the application’s densest row, status indicator, numeric formatter, action cell, editor, and validation state. Check text truncation, responsive width, dark mode, high contrast, and interaction inside custom cells. Prefer renderers that display domain state without performing data fetching or expensive calculation during render. Keep styling aligned with the broader product while preserving clear grid focus and selection states.

Understand the tier boundary

@ace-grid/core is the MIT starting point for React teams that need editing, selection, filtering, sorting, pagination, virtualization, CSV workflows, theming, and schema-aware state helpers. Evaluate Pro for formulas, validation, Excel workflows, grouping, tree data, sparklines, spanning, and advanced filtering. Evaluate Enterprise for server row model, charts, pivoting, and master-detail.

Use a representative production acceptance fixture

Create a fixture with stable row IDs, typed text, number, date, select, and boolean columns, one custom renderer, one custom editor, a validation failure, loading and empty states, a filtered view, pinned content, and enough rows and columns to exercise virtualization. Test this same fixture during upgrades. It proves the component contract, interaction behavior, and rendering cost more effectively than a large but passive demo dataset.

Inspect the shipped package boundary

Verify imports, generated types, license, peer dependencies, ESM and CommonJS outputs, and framework wrappers from the package actually intended for production. For Ace Grid, @ace-grid/core is the MIT-licensed React runtime; Pro and Enterprise extend that runtime for deeper workflows. Measure the production bundle produced by the application build rather than comparing package metadata in isolation.

Define upgrade acceptance tests

Pin a representative dataset and task suite in CI or release testing. Cover keyboard entry and exit, editing, validation, sorting, filtering, selection, pinned regions, virtualization, custom cells, loading, empty and error states, CSV behavior, and saved state. Record expected results rather than screenshots alone. This makes framework and Ace Grid upgrades reviewable and prevents regressions from being discovered only after users return to a frequently used work surface.

Live Ace Grid example

Core product grid

A real Ace Grid Core surface with editable customer rows, segment pills, status, ARR, health, and structured payload data.

CompanySegmentStatusARRHealthNext
HelioBankEnterpriseLive$820k94%Renew
Northstar AIStrategicLive$640k88%Expand
VaultPayEnterpriseReview$410k79%Validate
QuantivaMarketEscalate$295k62%Rescue

Production-shaped Core example

import { Grid, type CellValue, type GridColumn, type GridRow } from "@ace-grid/core";

const cell = (value: unknown, type: CellValue["type"] = "text"): CellValue => ({ value, type });

const rows: GridRow[] = [
  { id: "1", data: { company: cell("HelioBank"), owner: cell("Maya"), segment: cell("Enterprise"), status: cell("Live") } },
  { id: "2", data: { company: cell("Northstar AI"), owner: cell("Theo"), segment: cell("Strategic"), status: cell("Live") } },
];

const columns: GridColumn[] = [
  { key: "company", title: "Company", editable: true, sortable: true, filterable: true, width: 240 },
  { key: "owner", title: "Owner", editable: true, width: 160 },
  { key: "segment", title: "Segment", type: "select", options: ["Enterprise", "Strategic", "Market"], filterable: true, width: 180 },
  { key: "status", title: "Status", editable: true, filterable: true, width: 140 },
];

export function ProductGrid() {
  return (
    <Grid
      data={{ rows, columns }}
      columns={{ columnWidths: Object.fromEntries(columns.map((column) => [column.key, column.width ?? 160])), fillWidth: true }}
      layout={{ width: 1200, height: 520 }}
      virtual={{ enableVirtualization: true, enableHorizontalVirtualization: true }}
    />
  );
}

Choose the right React table abstraction

Use case Ace Grid fit Simpler option
Small read-only list Usually more component than the screen needs Use semantic HTML or a headless table
Editable product surface Built-in grid interaction and MIT Core adoption Custom table behavior becomes application code
Spreadsheet workflow Add Pro only for formulas, validation, Excel I/O, grouping, and related features Avoid paying for or building features the workflow does not use

Common questions

Is Ace Grid Core free to use?

@ace-grid/core is MIT licensed. Pro and Enterprise are commercial packages for spreadsheet and server-backed capabilities.

Sources