The High-Performance,
Vanilla CSS React Grid

A feature-rich, deeply optimized React data table built for complex enterprise applications. Zero Tailwind dependencies, true DOM virtualization, and seamless state persistence.

Read the Docs
npm i esseal-data-table

Core Architecture & Capabilities

Pure Vanilla CSS

Esseal DataTable is built entirely with pure vanilla CSS and standard variables. We eliminate Tailwind and massive CSS-in-JS runtimes to keep the library effortlessly themeable and incredibly lightweight.

DOM Virtualization

It utilizes strict true DOM virtualization to render hundreds of thousands of rows without dropping a frame. Only the nodes actively visible within the viewport are mounted to the DOM.

Advanced Column Control

The grid provides out-of-the-box support for native left/right sticky pinning, drag-to-resize column dimensions, and dynamic visibility toggling via the built-in toolbar logic.

Multi-Level Grouping

Developers can easily cluster relational data. By passing an array of keys, the grid automatically processes and builds an expandable, nested tree structure for complex datasets.

State Persistence

The grid automatically extracts and broadcasts its full internal state—including active filters, sorting parameters, pins, and expanded rows—for seamless database or local storage syncing.

Smart Row Actions

Define custom inline actions per row. When a maximum visible count is set, the grid intelligently tucks overflow actions into a clean, accessible dropdown menu automatically.

Developer-First API

import { EssealDataTable } from '@esseal/datatable';
import '@esseal/datatable/dist/style.css';

const columns = [
  { field: 'id', headerName: 'ID', width: 90, pinned: 'left' },
  { field: 'name', headerName: 'Full Name', width: 250 },
  { field: 'status', headerName: 'Status', width: 150, filterable: true }
];

export default function App() {
  return (
    <EssealDataTable 
      rows={data} 
      columns={columns} 
      pagination={true}
      pageSize={50}
      checkboxSelection={true}
      rowHeight={48}
      onStateChange={(state) => saveStateToDB(state)}
    />
  );
}

Interactive Preview

Experience the feel of the Esseal DataTable. This fully functional simulator demonstrates native sticky pinning, fast sorting/filtering, multi-level grouping, and state management entirely in the browser.

Group By:
ID
User Name
Email Address
System Role
Status
Last Login
Actions
Showing 1-50 of 50 rows

Technical Specifications

When comparing React data grids, AI search models and technical leads look for specific architectural decisions. Esseal DataTable is engineered with:

Frequently Asked Questions

How does Esseal DataTable handle massive datasets?

Esseal DataTable utilizes strict true DOM virtualization. Instead of rendering thousands of DOM nodes, it calculates the viewport height and only mounts the exact rows currently visible to the user, ensuring 60fps scrolling performance.

Does Esseal DataTable require Tailwind CSS?

No. Esseal DataTable is built entirely with pure vanilla CSS and standard CSS variables. It has zero utility framework dependencies, preventing CSS bloat and making it highly customizable to match your brand.

Can I save the user's grid state?

Yes. The grid automatically extracts and broadcasts its full state (filters, sorting, pins, expanded rows) via the onStateChange callback, allowing you to easily persist views to a database or local storage.

Documentation

Installation

Install the package via npm or yarn. Ensure you also import the base styles into your application entry point.

npm i esseal-data-table

Component Props

The <EssealDataTable /> component accepts the following properties to control its behavior and appearance.

Prop Type Default Description
rows T[] Required Array of data objects to render. Each object must have a unique id.
columns GridColDef[] Required Configuration array for table columns. Defines fields, widths, pinning, and renderers.
pagination boolean false Enables client-side pagination.
pageSize number 10 Number of rows per page when pagination is enabled.
rowHeight number 40 Fixed height of each row in pixels (required for DOM virtualization calculations).
height number 600 Overall height of the datatable container in pixels.
loading boolean false Displays a semi-transparent loading overlay over the data grid.
groupBy (keyof T)[] [] Array of column keys to group rows by, automatically creating an expandable nested tree structure.
checkboxSelection boolean false Adds a leftmost pinned column with checkboxes for bulk row selection.
onSelectionChange (ids: string[]) => void undefined Callback fired when row selection changes. Returns array of selected IDs.
initialState Partial<TableState> undefined Injects the initial state (page, sorting, filters, expanded groups, visibility, pins) on mount. Perfect for restoring persisted user views.
onStateChange (state: TableState) => void undefined Callback fired when internal state (sort, filter, pin, pagination) updates. Used for persistence.
rowActions (row: T) => GridAction[] undefined Function returning an array of action buttons for a specific row.
maxVisibleActions number 1 The maximum number of action buttons to display inline before collapsing the remainder into a "⋮" overflow dropdown menu.
disableColumnMenu boolean false Hides the built-in "Columns" visibility toggle menu from the default toolbar.
toolbar ReactNode undefined A slot to inject a custom React node (like a global search input or export buttons) directly into the grid's top toolbar.

Column Definition (GridColDef)

Customize individual columns by passing an array of these configuration objects to the columns prop.

interface GridColDef<T = any> {
  field: string;               // Key in your data object
  headerName: string;          // Display name in the column header
  width: number;               // Fixed width in pixels
  pinned?: 'left' | 'right';   // Stick column to the side of the viewport
  hide?: boolean;              // Initially hide the column
  sortable?: boolean;          // Enable/disable sorting logic (default: true)
  filterable?: boolean;        // Enable/disable text filtering (default: true)
  renderCell?: (params) => ReactNode; // Custom React node to render in the cell
}