Your product grows.
Its complexity doesn’t.

The grid and workspace layer for operational apps. Start with an editable table, then add a review step, a board, server validation, bulk actions — each one reuses the rules and behavior you already defined. You make the product decisions; Wit keeps them consistent.

Start building
An accounts-payable desk: every approval reviewed before it lands, saved to the AP’s own API, a limit finance changes live
Loading the approval desk…

For developers building operational software — review queues, CRMs, work orders, inventory — inside their own product, on their own data, backend and policies.

0.3 msone edit in a sorted 1,000,000-row grid
2.1×less main-thread work than AG Grid, fast scroll
1.3 msa 100,000-record pivot, updating live
0stale or blank cells, checked every frame
01Why Wit

Every feature you add shouldn’t multiply the wiring.

In most stacks each new surface brings its own copy of the rules, its own preview and its own idea of what is saved — and the glue between them is yours to maintain. With Wit, each addition reuses what is already there, so the behavior you can stop thinking about grows with every feature.

  1. 01An editable tableUsually: Cell events, your own validation, your own undo, wired per column.With Wit: Columns and rules. Every edit, paste and fill goes through one validated, undoable pipeline.
  2. 02A review step before bulk changesUsually: A second code path that computes the effect, then hopes nothing changed before it runs.With Wit: prepare shows the exact effect; commit applies exactly that, or refuses it as stale.
  3. 03A board, a calendar, a GanttUsually: Another library each, another copy of the records, sync code between them.With Wit: Views of the same records. Filters, permissions, rules and undo already apply.
  4. 04Server validationUsually: Map errors back to rows by hand, roll back what failed, keep what passed.With Wit: Your push answers per record: refusals roll back with the server’s reason, marked in every view.
  5. 05Bulk actions and an audit trailUsually: Each button re-implements the policy; the log guesses what happened.With Wit: One command from the toolbar, menu, palette or keys, under one policy; writes carry their action, the server’s answer is an event.
02What you stop thinking about

The hard questions, answered once, in the core.

Every operational app runs into the same questions once people review, save and fix records together. Wit answers them centrally, so your app doesn’t re-answer them in every screen. Where an answer is still being hardened, we say so.

In the core

What remains pending after part of an operation was rejected?

The server can refuse single records of a bulk change. Those roll back with its reason, marked in the table, on cards and in the inspector; the rest are saved, and what is still queued stays queued.

In the core · hardening

Was this exact change approved under the current rules?

A reviewed change commits exactly as it was previewed, or is refused as stale when its records changed in the meantime. It is never applied blind.

Next: a review also goes stale when the rules or permissions change while it is open.

In the core · hardening

Which edits belong to the save underway?

Every save reports what happened to each change it sent: saved, refused with the server’s reason, or still queued.

Next: a strict boundary, so edits made while a save is in flight wait for the next one, and manual saving sends only on Save.

In the core · hardening

Did this response concern the latest value?

Each change carries the value it was based on, so a server conflict keeps both sides for a person to settle instead of overwriting either.

Next: a slow validation result about an older value never replaces a newer one.

In the core · hardening

Which records actually contributed to this total?

A pivot cell opens exactly its records in the table, as filters you can act on; a chart drills down to its records.

Next: measures with their own condition (“won deals only”) open only their contributors.

03Clear lines

Your product. Wit’s consistency.

You keep control of everything that makes your product yours. Wit owns the consistency between the pieces — and is explicit about where its responsibility ends.

Yours
  • Your backend. Save in your API’s own request shape; Wit hands you the changes and reads your answer.
  • Your policies. Rules, permissions and limits, declared once and changed live.
  • Your components. Cells, editors, cards, panels and toolbar, in React or plain DOM.
  • Your workflow and its record. The steps people take, and the durable audit you keep.
Wit’s
  • One record everywhere. Table, board, calendar, Gantt and inspector show and change the same records.
  • One write path. Every gesture and command is validated, permission-checked and undoable the same way.
  • The save lifecycle. Queue, check, send, and an outcome per record; manual or automatic.
  • Issues where people look. A broken rule or a refusal shows on the cell, the card and the inspector.

Deliberate boundaries: one grid is one table, and its views are projections of it. The workspace is optional and loads only when used. Wit names each action and reports each outcome; where the audit lives is your call.

04Depth, shown

Not a screenshot. A sequence.

A polished table is easy to demo. What matters is what happens when a review, a policy change and a server’s answer meet. The approval desk at the top of this page plays it end to end.

  1. 1

    Review a bulk approval

    The dialog shows exactly which invoices change and how, before anything is written.

  2. 2

    Finance lowers the limit

    Every invoice is checked again at once; the ones now over it are marked in every view.

  3. 3

    Submit to your API

    The request is your accounts-payable system’s own body, with each decision named.

  4. 4

    The server refuses one

    That invoice rolls back with its reason; the others are saved; nothing else is lost.

  5. 5

    Read what happened

    The audit trail says who approved what, where, and what the server answered.

05Views

One record, every view — when you need it.

The grid stands on its own. When a record also needs to be a card, a calendar event or a Gantt bar, Wit Grid keeps it one record — the same filters, selection, permissions, validation and undo in every view. You declare a rule once; you don’t wire each view to the others.

Loading the workspace…

Table

Dense operations: pinned columns, grouping with totals, spreadsheet editing.

Kanban

Workflows with WIP limits, swimlanes and rules for what a column needs.

Calendar

Scheduling by month, week or hour; drag to reschedule, drop to plan.

Gantt

Dependencies, baselines, constraints and the critical path.

Gallery

Visual records with covers, sections and your own card layout.

Chart

Counts and totals by any field, with drill-down to the records.

06Analysis

Pivot tables, native to the grid.

Rows by some fields, columns from the values of others, every cell an aggregate. Pivoting is grid state, not a plugin — filtered, live, saved with views, exported and drilled into like everything else.

Rows, columns, values

Any field across or down: dates by month or quarter, numbers by range, the top values with the rest as Other.

Show values as

Share of the grand, row or column total, running totals, change from the last column, rank.

Heatmap and drill-down

Shade cells by value; double-click one to list its records and open any in the inspector.

Server-scale

Pivot millions of rows on your server: one answer per pivot, groups opened in the browser.

Excel that keeps it

Column groups merged, totals kept, every number typed in its format.

Built by your users

A field list to drag into, Pivot by column in every header, a Pivot tab saved with your views.

07Performance

Measured, not promised.

Same Chrome, same data, real input. Head to head against AG Grid on scroll, and against our own previous engine on live data — every number on this page comes from a recorded benchmark run.

Head to head · scroll

Less main-thread work than AG Grid, in every scenario.

  • 2.1×Fast fling90 flicks of 2,400 px
  • 1.8×Plain scroll100,000 rows × 50 columns
  • 1.6×Wide grid200 columns, sideways
  • 1.4×Custom cellseach grid’s own renderers
Live data · per tick

Changes cost what they touch, not what you hold.

  • One edit, 1,000,000 sorted rows31.7 ms0.3 ms
  • Live pivot, 100,000 records101 ms1.3 ms
  • Board, calendar, gallery, chart · 50,000 records83–143 ms4–15 ms
  • React, a new rows prop · 1,000,000 rows130 ms7.5 ms

AG Grid Community 36.2.0 with its defaults, same Chrome and data, real input, 5 paired rounds (30 Sep 2026); live data against our own previous engine, median per tick, one machine. Full scoreboard and method

Virtualized both ways

Rows and columns: 100,000 × 1,000 keeps a few hundred cells in the DOM.

Cell-level updates

A centralized engine with targeted subscriptions repaints the cell that changed — never the tree.

Your renderers, first-class

Custom cells as React components or plain DOM renderers — part of the engine, never an afterthought.

Real HTML, no canvas lock-in

Native text selection, accessibility roles, CSS theming and browser find all keep working.

08Editing

Editing that feels native, not bolted on.

Wit Grid treats editing as a core workflow, not an event callback sprinkled onto cells: every keystroke, paste and drag goes through one validated, undoable pipeline.

Keyboard-first

Arrows, Tab, Enter, F2, type-to-edit — the way spreadsheet users expect.

Ranges and fill handle

Select ranges, drag the handle to fill a series.

Copy and paste

To and from Excel and Sheets, with types, validation and one undo step.

Transactions and undo

Every gesture is one transaction: validated, undoable, reported.

Validation

Rules per column and per row; refused writes are explained, not dropped.

Formulas and fields

People add fields, links, lookups, rollups and formulas themselves.

09Developer control

You shape it. Wit runs the machinery.

Configuration for the common cases — columns, views, record roles, rules and permissions. An API for everything else. Your own components where they matter — cell renderers and editors in React or plain DOM, card displays, slots, sidebar panels and commands. Underneath, Wit handles rendering, editing, validation, history and sync.

import {
  Grid,
  selectType,
  personType,
  currencyType,
} from '@witbybit/wit-grid-react';

const columns = [
  { field: 'deal', header: 'Deal', width: 240, pinned: 'left' },
  { field: 'stage', header: 'Stage', type: selectType(STAGES, { variant: 'fill' }) },
  { field: 'owner', header: 'Owner', type: personType({ people: REPS }) },
  { field: 'amount', header: 'Amount', type: currencyType({ decimals: 0 }) },
];

export function Deals({ rows }) {
  return (
    <Grid
      rowModelType="client"
      rows={rows}
      columns={columns}
      getRowId={(row) => row.id}
      rowSelection="multiple"
    />
  );
}
The primitives you build with
GridApiState, editing, selection, undo, clipboard, export
ColumnDefTypes, renderers, editors, validation, value getters
Row modelsclient · infinite · server, one UI
EventsTyped; local and collaborators’ changes told apart
WorkspaceViews, summary, slots, parts, extensions
PersistenceSaved views, layouts, fields
ThemingTokens, density, built-in themes
10Data

From local arrays to server-scale data.

Start with local data. Grow into server-driven datasets without replacing the UI layer: stable row identity, the same sorting, filtering and grouping contracts, cache and refresh controls.

Client

An array in memory: sort, filter, group and edit instantly.

rowModelType='client'

Infinite

Pages loaded as people scroll, with loading rows in between.

rowModelType='infinite'

Server

The server sorts, filters, groups and pivots; the grid asks for blocks.

rowModelType='server'
11Data integrity

Validation, quality and conflicts, built in.

Wit Grid does not just display data. It helps people trust it.

Required and valid

Inline errors where the value is, a list of what is wrong, and gates on submit.

Duplicates

Values that must be unique are checked across the whole dataset.

Live conflicts

A collaborator’s change to the cell you are editing is caught and resolved, not lost.

Activity

Who changed what, per record, alongside comments and files.

12Product fit

Make it feel native to your app.

Wit Grid should disappear into your product until people need its power.

Design tokens

Colours, radii, density and fonts — or one of the built-in themes as a start.

Density and modes

Compact to comfortable, light and dark, switched live.

Chrome that fits

Hide toolbars and parts, add your own panels, slots and card widgets.

Embedded or full-screen

A cell in a form or the whole page — the same engine either way.

13Positioning

Why not just a table, a spreadsheet or a grid?

Wit Grid is a toolkit for your own product — not a hosted app builder you embed, and not someone else’s app.

NeedBasic tableSpreadsheetGrid componentWit Grid
Large datasetsNoLimitedYesYes
Built into your own appYesNoYesYes
Spreadsheet-grade editingNoYesYesYes
Multi-view workspaceNoLimitedRareYes
Same records across table, board, calendar, GanttNoNoRareYes
Server-scale row modelsNoNoYesYes
Pivot tables, client and server, in the coreNoYesVariesYes
Your own workflows and widgetsMediumLowMediumHigh
New features reuse your rules and policiesNoPartlyRareYes
Per-record outcome when your server refuses part of a saveNoNoNoYes
14Use cases

Made for operational software.

Operational software needs dense data, editing, validation, boards, timelines, charts, permissions and live updates — usually stitched together from separate libraries that each keep their own copy of the records. With Wit each of these starts as a grid; the board, calendar and inspector read and write the same records, so an edit, a refusal or an undo means the same thing everywhere.

CRM and revenue

Pipelines with a workflow, what-if forecasts, weighted totals and a deal room per record.

Financial operations

Ledgers and reconciliations: formulas, totals by group, read-only closed rows and activity on every record.

Compliance

Controls with owners and evidence, required fields that hold submission, and history.

Logistics

Shipments on a timeline and a board, live updates as they land, exceptions surfaced.

Inventory

Hundreds of thousands of SKUs, server-side grouping by warehouse, bulk edits in one step.

Product planning

Roadmaps as a Gantt with dependencies and a critical path, the same items as a board.

Admin platformsInternal toolsData reviewMarketplace operationsSupport queuesHR and recruiting
15Capabilities

Everything a serious grid needs, in the core.

The depth behind every section above: editors, filters, charts, Excel, saved views, live teammates, conditional formatting and more — one engine, not a stack of plugins.

20+ native cell editors

Selects, tags, people, dates, ranges, ratings, toggles, colours, sparklines — themed, keyboard-first, server-loaded options.

type: "select"

A board that runs the work

Status columns with WIP limits and totals, swimlanes, multi-card drag with a drop slot, blocked work flagged.

kind: 'kanban'

Inspector & command palette

Every field edited by its column’s own editor, with comments and activity; Ctrl/⌘ K reaches every view and record action.

Ctrl + K

A Gantt that schedules

Outline and timeline on one row model: dependencies with lag, working calendars, the critical path, baselines and workload. You see the knock-on before a move reschedules anything.

autoSchedule: 'push'

Works offline

Records stay on the device: the grid opens with what the user saw last, keeps working without a network, and syncs every edit to your server when it is back.

offline()

Excel that keeps formats

Currency, percent and dates stay typed; groups export as collapsible outlines. No dependency.

exportExcel()

One filter, every surface

A column’s filterDef drives the header funnel, floating row, sidebar, chips and query builder — relative dates included.

filterDef

Teammates, live in the grid

Feed in who is where: cursors glide between cells, rings sit on the cards and bars they are on, and their edits stay out of your undo.

api.setPresence()

Views, personal or shared

A view is a destination: a board with swimlanes, a schedule at a zoom, with its own filters, sort and columns. Yours, the team’s or the app’s, each saved as its owner acknowledges.

api.views.saveAs()

Grouping, trees & detail

Expandable groups with live aggregates, parent-child trees, and a sub-grid per row.

groupBy

Conditional formatting

Colour scales, data bars and icon sets scaled to each column, repainting as live data moves — and kept in Excel.

kind: 'dataBar'

Bulk edits, one undo step

Select across any view and move, assign, re-prioritise or shift dates for all of them: one transaction, validated and undoable.

api.transaction()

Charts, built in

Chart a selection or a column per category on a crisp canvas; click a bar to filter the grid.

createGridChart()

A minimap of every row

A strip beside the scrollbar marks selection, recent edits and issues across 100k rows. Click to jump.

minimap

Not shipped yet: real-time multiplayer editing (presence is in; syncing edits between people runs through your backend today), Excel import (export is in), and adapters beyond React (the core runs in any page).

Build more product. Maintain less glue.

Start with a grid. Add the reviews, views and server rules your users need — on the same records, under the same rules, without rewriting what you built.

Source-available for evaluation · read the license