Views

Views

Every view reads the same row model and the same .base file; type: picks one. 17 of 17 are built; the rest are planned, each with its stock library already chosen and installed (docs/VIEWS.md). A planned type in a .base file draws the table with a one-line notice.

Which views are built

View.base typeStatusStock partPriority
Table
Decided by the table lane: headless engine, Notion-like surface ours, 36 KB gz, 22/22 checks.
table (Bases)builtTanStack Table v9 + Virtual
@tanstack/table-core@9.3.1, @tanstack/virtual-core@3.19.7
now
Pivot
A transform before the table: same menus and drill-down, no new library.
pivotbuiltgrammar.pivot() + TanStack
@tanstack/table-core@9.3.1
now
List
Same virtualiser as the table, another row template; 0 KB extra.
list (Bases)builtTanStack Virtual
@tanstack/virtual-core@3.19.7
later
Cards / gallery
`lanes` give grid now and masonry later in one virtualiser; 0 KB extra. Live in the report.
cards (Bases)builtTanStack Virtual (lanes) + CSS
@tanstack/virtual-core@3.19.7
now
Image / media grid
Cards plus a lightbox; the mature MIT one, 12 CSS variables. lightGallery is GPL, Fancybox paid.
cards + lightbox:builtPhotoSwipe
photoswipe@5.4.4
soon
Chart
The `chart:` block is Vega-Lite: the grammar agents and Altair already write; every chart type asked. 283 KB gz, lazy. Live in the report.
chartbuiltVega-Lite + vega-embed
vega@6.4.0, vega-lite@6.5.0, vega-embed@7.3.0
now
KPI card / stat
The survey's kit as the SPEC renamed it; a 60-line SVG sparkline, no chart engine. Tremor is React + Tailwind and stale.
kpibuilt<data-kpi> + <data-value> + <data-sparkline>
none (ours)
soon
Kanban / board
Bases' own type since 1.14. Headless drag (7 KB) that never moves a node, so edits are proposals and columns virtualise. Live in the report.
kanban (Bases)builtPragmatic drag and drop (+ hitbox)
@atlaskit/pragmatic-drag-and-drop@4.0.0, @atlaskit/pragmatic-drag-and-drop-hitbox@3.0.0, @tanstack/virtual-core@3.19.7
soon
Calendar
Framework-free, MIT, resource and timeline views free, 29 CSS variables. FullCalendar and Schedule-X paywall what we'd use.
calendarbuiltEvent Calendar (vkurko)
@event-calendar/build@5.18.1
later
Timeline / Gantt
Lanes of runs on a zoomable axis is its whole job; dual Apache/MIT. Frappe Gantt only if dependencies are ever needed.
timelinebuiltvis-timeline
vis-timeline@8.5.5
later
Map
The engine Obsidian's own Maps plugin uses, with its ten keys as-is; basemap self-hosted (PMTiles), never a tile CDN.
map (Bases)builtMapLibre GL + PMTiles
maplibre-gl@6.16.0, pmtiles@4.5.0
later
Tree / hierarchy
TanStack sub-rows on the table and list views; 0 KB extra. Not a new type.
table / list + tree:builtTanStack Table sub-rows
@tanstack/table-core@9.3.1
soon
Graph / network
Zach's call; also his Block View chassis. A React island: 128 KB gz with React, 61 KB where React is already loaded. `layout: {engine: mermaid}` draws the same nodes and edges as a static Mermaid flowchart, its own chunks, fetched only when such a view opens.
graphbuiltReact Flow (@xyflow/react)
@xyflow/react@12.12.0, react@19.3.1, react-dom@19.3.1, @dagrejs/dagre@3.1.3, mermaid@12.2.0
soon
Record / peek / detail page
The lane's peek, generalised into the one record surface every view opens.
recordbuiltThe lane's peek, generalised
none (ours)
now
Form / editor
No framework-free stock form fits; native inputs over the dataset's own property schema, submits as proposals.
record + edit: truebuiltNative inputs over the property schema
none (ours)
later
Compare (side by side)
No maintained compare component exists; it is the table on transposed rows, plus a 4 KB image slider.
comparebuiltTanStack Table on transposed rows
@tanstack/table-core@9.3.1, img-comparison-slider@8.0.7
soon
Raw source
Zach, 2026-10-26: "almost a plain Excel chart of what the data set is behind it". The same virtualiser as the table and list, over the rows and the columns; every key of every row, each value as stored, the record as it sits in its file (CONTRACT §24). 0 KB extra.
sourcebuiltTanStack Virtual
@tanstack/virtual-core@3.19.7
now

Every view, live

Each block is one entry of an example's .base file. Preview runs the real kit on the example's real data (it starts when you scroll to it); Code is the entry that draws it, cut from the file as written.

Table type: table

Live

Rows under a sticky header: two group levels with fold and summaries, multi-sort, a display per column, units in the header or inline.

The live view starts when it scrolls into sight.

From the example robotparts actuators · two group levels, summaries, bars in cells · stock part @tanstack/table-core@9.3.1

Pivot type: pivot

Live

Groups x split columns, one summarised value per cell; a cell opens the records behind it.

The live view starts when it scrolls into sight.

From the example Models × benches · stock part @tanstack/table-core@9.3.1

List and tree type: list

Live

One line per row: the title, then its properties inline or on their own lines, under group headings; with tree: an outline that folds.

The live view starts when it scrolls into sight.

From the example Vibe Tracks feature tree · with tree:, an outline that folds · stock part @tanstack/virtual-core@3.19.7 · also covers Tree / hierarchy

Cards and media grid type: cards

Live

Bases' cards: an image, the title and the view's properties per card, group headings; lightbox: true opens each image full screen with its caption and source.

The live view starts when it scrolls into sight.

From the example robotparts photos · lightbox: true opens each photo full screen · stock part @tanstack/virtual-core@3.19.7 · also covers Image / media grid

Kanban type: kanban

Live

Columns are groupBy's values in groupOrder, each with its count; dragging a card proposes a data edit (derived properties refuse), dragging a column writes groupOrder; both work from the keyboard.

The live view starts when it scrolls into sight.

From the example Vibe Tracks feature board · a drag proposes an edit; the host decides · stock part @atlaskit/pragmatic-drag-and-drop@4.0.0

Chart type: chart

Live

Any Vega-Lite chart of the view's rows: presets per .base, an Encode menu, a hover card with the photo, Ashby envelopes and index lines, the same rows as a table one click away.

The live view starts when it scrolls into sight.

From the example Actuator charts · inside chart: the vocabulary is Vega-Lite's · stock part vega@6.4.0

KPI type: kpi

Live

One stat card, or one per group: the value with its unit and basis, a delta coloured by which way is better, an SVG sparkline, "computed from N runs"; the headline card draws its history as a chart.

The live view starts when it scrolls into sight.

From the example Vibe Tracks KPIs · the delta is coloured by which way is better · no library: ours

Calendar type: calendar

Live

Rows with a date (or a start and end) on month, week, day and list grids, coloured by group; an event opens its record; drag one to propose a new date.

The live view starts when it scrolls into sight.

From the example Releases and daily notes · stock part @event-calendar/build@5.18.1

Timeline type: timeline

Live

Rows as bars (start to end) or points on a zoomable time axis, in lanes from groupBy, nested from subGroupBy, coloured by a property; a bar opens its record.

The live view starts when it scrolls into sight.

From the example robotparts releases and lanes · stock part vis-timeline@8.5.5

Map type: map

Live

Rows with coordinates as markers on a bundled Natural Earth world map (no tile server); rows at one point count together; marker colour from a property; a marker opens its records.

The live view starts when it scrolls into sight.

From the example robotparts sellers by country · a bundled world map, no tile server · stock part maplibre-gl@6.16.0

Graph type: graph

Live

Rows as nodes, edges from a property listing other rows' ids. Engine flow (default): React Flow laid out by dagre; group by draws subflows; pan, zoom, minimap. Engine mermaid: the same graph as a static Mermaid flowchart. A node opens its record.

The live view starts when it scrolls into sight.

From the example 1-DOF rack wiring · stock part @xyflow/react@12.12.0

Record and form type: record

Live

One row as a property sheet in sections: values with unit, basis and source, every value behind it; with edit: true, a form that proposes edits.

The live view starts when it scrolls into sight.

From the example Actuators side by side · with edit: true the record is a form · no library: ours · also covers Form / editor

Compare type: compare

Live

2 to 6 rows side by side, one line per property, the better value marked, differences only, a photo pair as a slider.

The live view starts when it scrolls into sight.

From the example Actuators side by side · stock part @tanstack/table-core@9.3.1

Time series

Dates are grouped in the core, so every view gets the same buckets: a group level takes by: day | week | month | quarter | year, and a chart's date channel takes the same by:. The date is the one written: a date-only value is never shifted, and a datetime is bucketed by the calendar date in its own offset, never the viewer's time zone. Weeks start on Monday. More in Time groups and peek trail.

by:Bucket key (sorts in time order)Label
day2026-10-20Tue 20 Oct 2026
week2026-10-19Week of 19 Oct 2026
month2026-10Oct 2026
quarter2026-Q4Q4 2026
year20262026

Rows grouped by week groupBy: {property, by: week}

Live

A table whose group level is a date bucket: one group per week, oldest first; the rows inside a week keep the view's sort. gaps: true would keep the empty weeks too.

The live view starts when it scrolls into sight.

From the example ML experiment tracking

A time axis x: {field, by: week}

Live

A chart whose x is a week: one band per bucket, labelled as the table labels it, every week from the first to the last, so an empty week is an empty band and the axis holds still while you filter. WHY not Vega-Lite's own timeUnit: its weeks start on Sunday and it reads dates in the viewer's zone.

The live view starts when it scrolls into sight.

From the example ML experiment tracking

Timeline type: timeline

Live

Bars from start to end (or points), in lanes from groupBy, nested by subGroupBy; scroll to zoom within zoom: {min, max}.

The live view starts when it scrolls into sight.

From the example robotparts releases and lanes

Calendar calendarView: week

Live

The same dates on a week grid; month, day and list are the other grids. Dragging an event proposes a new date to the host.

The live view starts when it scrolls into sight.

From the example Releases and daily notes

KPI sparklines and gates kpi: {spark, gate}

Live

One card per group, each with its history as a sparkline (spark: {x, y}) and a gate line; with compare: a card also shows its delta, coloured by which way is better.

The live view starts when it scrolls into sight.

From the example ML experiment tracking

Explain the data

A view can open with its answer and make its numbers readable: intro: puts markdown and KPI cards above the rows, rollup: collapses a dimension, columnGroups: adds a header over related columns, and the stats, range, value, dist and markdown displays draw a number with its spread. More in Explain the data.

An answer first, rolled up intro: {text, kpi} · rollup:

Live

Markdown and KPI cards above the rows, then every model ranked with the actuators rolled away (each cell a median with its spread). Roll up in the toolbar of the full case brings them back.

The live view starts when it scrolls into sight.

From the example Actuator models · benches, leaderboard, parameters

Column groups columnGroups:

Live

A header over related columns (Friction, Capture, Drivetrain, Driver); display: value puts the basis mark beside each number and its 95 % interval in the hover.

The live view starts when it scrolls into sight.

From the example Actuator models · benches, leaderboard, parameters

Sub-columns for a value and its interval display: stats

Live

One property split into value, low, high and basis, each in its own column under the property's label, instead of the range squeezed into one cell.

The live view starts when it scrolls into sight.

From the example Actuator models · benches, leaderboard, parameters

Distributions on one scale display: dist

Live

Every run as a dot, their median a tall tick, on one scale down the column with its ends drawn in the header, so rows compare at a glance.

The live view starts when it scrolls into sight.

From the example Actuator models · benches, leaderboard, parameters