A spreadsheet in plain text.
A .tsvt file is the spreadsheet — a tab-separated grid whose cells are values or =formulas that address other cells in A1 notation, computed by a processor, versioned as text, diffed line by line.
Student⇥Math⇥Reading⇥Science⇥Average⇥Pass Alice⇥85⇥90⇥78⇥=round(avg(B2:D2), 1)⇥=if(E2 >= 70, 1, 0) Bob⇥72⇥68⇥80⇥=round(avg(B3:D3), 1)⇥=if(E3 >= 70, 1, 0)
| A | B | C | D | E | F | |
|---|---|---|---|---|---|---|
| 1 | Student | Math | Reading | Science | Average | Pass |
| 2 | Alice | 85 | 90 | 78 | 84.3 | 1 |
| 3 | Bob | 72 | 68 | 80 | 73.3 | 1 |
Same file, two readings: the text you commit, and the sheet your processor computes. Shaded cells hold formulas — hover or tap one and the formula bar shows what it computes.
Why TSV, not CSV
Formulas are full of commas. Because fields are separated by tabs, =if(A1, C3, D3) is written verbatim — no quoting, no escaping, no dialect. Every cell in a .tsvt file reads exactly as it would in a formula bar.
Spreadsheets earned their place by making computation visible: a grid you can read, formulas you can point at. What they never earned is a file format — binary blobs and XML archives that no diff can explain and no text editor can open. tsvsheet keeps the grid and the formulas and drops everything else: one row per line, versioned like source code, reviewed line by line.
Because the file holds =round(avg(B5:D5), 1) and never 71.7, a diff shows the decision someone made — one changed number — while the consequences stay computable: recompute both sides of a commit and compare, merge two people's edits to different rows, blame a formula, gate the whole thing on check. Working a sheet through git →
Formulas that read like pipelines
The expression language is Excel-faithful — ^, &, postfix %, A1 cells and ranges — plus one unix-native addition: the pipe. expr | fn(arg) feeds the expression in as the function's first argument, so a transformation reads left to right in execution order instead of inside-out:
=B2 | round(1) ≡ =round(B2, 1) =concat(A2, " ", A3) | len ≡ =len(concat(A2, " ", A3)) =sum(B2:B7) | round(2) ≡ =round(sum(B2:B7), 2)
The pipe is pure sugar over function calls — the two spellings are the same formula, and everything downstream (dependency order, memoization, explain) sees an ordinary call, while your sheet keeps the spelling you wrote.
Live sheets, right here
These grids are real .tsvt files. Load the engine — the actual Go implementation, compiled to WebAssembly, running entirely in this page — and every cell becomes editable: click, type a value or an =formula, and watch the sheet recompute.
| Student | Math | Reading | Science | Average | Result |
| Alice | 85 | 90 | 78 | 84.3 | Pass |
| Bob | 72 | 68 | 80 | 73.3 | Pass |
| Carol | 95 | 88 | 91 | 91.3 | Pass |
| Dave | 60 | 55 | 70 | 61.7 | Fail |
Each Average reads its row's scores; each Result reads the Average beside it. Change a score and both follow.
| Category | Monthly | Share % |
| Compute | 4200 | 48.8 |
| Storage | 1900 | 22.1 |
| Network | 1100 | 12.8 |
| Observability | 800 | 9.3 |
| CI | 600 | 7 |
Every share reads sum($B$2:$B$6) — change one number and the whole column reflows.
Want the full experience — formula bar, keyboard navigation, row/column edits, precedent highlighting, the raw .tsvt pane? Open the playground →
One engine, every workflow
The tsvsheet CLI is a strict unix citizen: text in, text out, exit codes for scripting. The same engine also serves a browser editor and a terminal UI — no frontend re-implements a single formula.
$ tsv render sheet.tsvt # compute and print the grid $ tsv check sheet.tsvt # validate formulas and references $ tsv explain D5 < sheet.tsvt # trace how one cell was produced $ tsv serve sheet.tsvt # local browser spreadsheet editor $ tsv tui sheet.tsvt # terminal spreadsheet editor
A .tsvt can carry a #! shebang and # comments, so a sheet is directly executable — render is the default command. Computed output is plain TSV: pipe it to column -t, load it with d3.tsv(), feed it to gnuplot, commit it to git. Formulas draw on 140 built-in functions — Excel-faithful math, text, dates, lookups, and more.
Built for agents
An AI agent works best on artifacts it can read, edit, diff, and verify as text — which is precisely what a .tsvt is. An agent edits three characters, the diff shows three characters, CI recomputes the sheet, and the review shows exactly what changed and what it rippled into.
checkas a gate — validate every formula and reference, with exit codes an agent (or CI) can act on.explainas ground truth — the evaluation trace of any cell, so "why is D5 wrong?" has a mechanical answer.parseas structure — the typed AST as JSON, stable enough tojq.- tsvsheet.mcp — the engine's render/check/explain surface as MCP tools, so agents drive spreadsheets through files, not screenshots.
Sheets where you already write
A fenced ```sheet block in Markdown renders as a computed grid — in Go pipelines through tsvsheet.goldmark, in JS pipelines through tsvsheet.remark, and in your vault through tsvsheet.obsidian, which also gives .tsvt files a live view. tsvsheet.lsp brings diagnostics, hovers, and completion to any editor that speaks the language-server protocol; dedicated VS Code and IntelliJ extensions are built on it and not yet published. The full catalog — editors, agents, servers, libraries — is on the tools page.
One grammar, every runtime
The language is specified grammar-first: the ANTLR4 grammar in tsvsheet is the source of truth, implementations follow it, and the same file computes identically in every runtime.
| tsvsheet | The grammar-first language home: ANTLR4 grammar and the specification |
|---|---|
| tsvsheet.go · tsvsheet.js | Language implementations — the Go engine, and the same engine as WebAssembly with a typed JS API and a <tsv-sheet> web component |
| tsvsheet.goldmark · tsvsheet.remark · tsvsheet.obsidian | Markdown and Obsidian integrations — sheets computed inside your notes |
| tsvsheet.lsp · tsvsheet.mcp | Editor and agent tooling: language server and MCP server |
| tsvsheet.api | The sheet API server — the edit language over HTTP: document plane, change feed, computed reads |
| go-tsvsheet | The engine as an importable Go library — parse, compute, and inspect .tsvt files |
Get started
$ brew install tsvsheet/tap/tsv $ printf 'a\tb\tsum\n2\t3\t=A2+B2\n' > first.tsvt $ tsv render first.tsvt a b sum 2 3 5
Scoop on Windows, deb/rpm packages, prebuilt binaries with verifiable provenance, or go install — every way in is on the install page. Prefer the browser? The playground runs the same engine as WebAssembly — no install, nothing leaves your machine. Go programs import go-tsvsheet; the JS package tsvsheet.js (typed API + <tsv-sheet>, consumed straight from the repository) is what powers the live sheets on this page.