tally://guide/extend and searches it with tally_where.
Change how a column type or kind is drawn
Pass a renderer keyed by the column type name first, then its kind. It receives value, text, row, column, type and format. Keep the data and the query untouched; only the cell changes.
Change how a cell is edited
Pass an editor keyed by type name or kind. It receives value, column, commit(value, move?) and cancel(). Call commit to write through grid.setCells with undo.
Add a new column type
Implement ColumnType: name, kind, parse, format, compare, is, operators, facet, card, optional detect and jsonSchema. Register it and pass the registry to createSchema. Servers receive the type name through the schema route, so pass the same registry to connectHttpSource on the client.
Shape a column: label, width, pin, aggregate, avatar, subtitle, sparkline, relative, card role
Column options drive the default renderers and the menus. Nothing else is needed for an initials tile, a secondary line, a sparkline before a number or a relative date line.
Theme, colors, fonts, density, radius
Override —tally-* tokens on .tally or any ancestor. Dark mode follows color-scheme or theme=“dark”. Target states through data attributes such as [data-selected] or [data-sign=“down”]. Density is a view property.
Translate or reword UI text
Every string in the UI is a key of TallyLabels. Pass the ones to change; the rest keep defaultLabels.
Hook keyboard and mouse actions, command palette, inspector
Every input becomes a GridIntent first. Return true to consume it. Cmd/Ctrl+K emits commandPalette, Space emits inspect, so a host binds its own palette or side panel without forking the grid.
Replace or extend the toolbar
Children render at the end of the default toolbar, toolbarStart before the filter bar. Pass toolbar={false} and compose the exported parts with useGridContext for a different arrangement.
Serve the grid from a SQL database
The adapter compiles validated protocol requests to SQL and passes the conformance suite on SQLite, Postgres and MySQL. Mount the Fetch handler on any framework. For SQL Server or another engine implement SqlDialect. For Laravel use tally/laravel.
Serve the grid from a Laravel app
Extend Grid with the Eloquent query and the column definitions, then register it with the Route::tally macro. The adapter validates every request against the protocol JSON Schema, compiles it with the query builder and passes the conformance suite on SQLite, Postgres and MySQL. Override columnMap(), flags(), mutable(), maxLimit() or dialect() on the grid.
Connect the grid to an HTTP API
Any server that answers GET /schema, POST /query, PATCH /rows and GET /events speaks the protocol. One call fetches the schema and returns a DataSource with live patches over SSE. For an API that does not speak the protocol, implement DataSource from tally-core directly: capabilities, query, optional mutate and subscribe.
Run the grid straight against Supabase
Filters, search, sorts and pages compile to PostgREST, edits go through the table API, Realtime delivers patches. Groups, aggregates and facets are computed from the loaded page.
Cache and dedupe requests, or run local-first
Wrap any source in TanStack Query for caching and devtools, or run over a TanStack DB collection so filters execute locally and edits go through the collection persistence handlers.
Push live updates into the grid
A source with live capability publishes patches; the grid merges them, marks changed cells and re-ranks rows by the view sort. The HTTP handler relays patches over server sent events and the HTTP source reconnects on its own.
Answer natural language with a validated query
The model answers in Tally query text which is parsed against the schema with one repair round; only a query that parses is returned. In the browser call the provider through a same-origin proxy that adds the API key.
Add a column the model fills per row
Declare the column ai: true, non filterable, non sortable, non groupable. Values stream in as live patches and are cached per row. designColumn turns a prompt into a column definition plus the fill instruction; wire it to the addColumn handler of the ai prop.
Use the grid engine from Vue, Svelte or Solid
The engine is tally-core and renders nothing. Each binding keeps one Grid per component (recreated when schema, source or format change, keeping the view), subscribes to its stores with the framework reactivity primitive and unsubscribes on unmount. Build the markup yourself; the full component only exists for React.
Saved views, URL state, formatting rules, density
A View holds filter, sort, group, columns, density, footer and rules. Serialize it for a URL or a database, restore it with reconcileView so renamed columns drop out cleanly. Conditional formatting lives in View.rules.
Phone layout and the detail sheet
Below cardsBelow pixels rows render as cards grouped by card role. Tapping a card opens a sheet with every visible field. Pass detail={false} to disable it or a function to render the sheet body.
Import or export CSV
Import detects column types and enum options from the samples and reports issues per cell. Export formats with the schema so enum labels and dates come out as displayed.
Validate requests on your own server
Parse the wire shape then check columns, operators, arities and aggregates against the schema. Throws TallyError invalid_query with one detail per problem. JSON Schema files serve adapters in other languages.
Prove a new adapter matches the reference engine
The suite replays every filter, sort, group, aggregate, facet and page case over a fixture dataset with empties in every column and diffs the result against the in-memory executor. Create the adapter with today set to CONFORMANCE_TODAY.
Write or parse a filter in the query language
Columns resolve by id, label or alias, enum values by value or label. Numbers accept 2k and $5,000, dates accept 2026-01, today, last 30 days, this quarter. Errors carry offsets. Use the tally_parse_query tool to check a string before shipping it.