Grist
Spreadsheet meets database for structured data
Grist is an open-source modern relational spreadsheet that combines the flexibility of a spreadsheet with the robustness of a database. It supports formulas, Python, and access rules.
Key features
- Relational spreadsheet engine
- Python formula support
- Granular access control
- Custom widgets and views
Strengths
- Powerful data modeling
- Self-hostable core is full-featured
Grist replaces
Last reviewed Aug 26, 2026 · 938 words
Grist is the spreadsheet where a formula column is a line of Python, every table can reference another, and an access rule can hide a row from one user and a column from another. That combination, not the Airtable-style grid, is why you would pick it over NocoDB or Baserow. The self-hosted build is the whole product, Apache-2.0 with 11,600 stars, and every document is a single SQLite file on disk that you can back up with cp. The catalogue rates it Medium, and the difficulty is concentrated in one place: deciding how people will log in.
Every document is a SQLite file, and that simplifies everything
Documents live under /persist/docs/ as .grist files, which are SQLite databases with a few Grist tables added. Backup is an rsync of that directory; a corrupted deploy is fixed by copying a file back; and if Grist vanished tomorrow, sqlite3 reads your data out without it. The container needs 512 MB, runs comfortably on a Pi 4 for a household, and is 1 service with no external database:
services:
grist:
image: gristlabs/grist:latest
ports:
- "8484:8484"
environment:
APP_HOME_URL: https://grist.example.com
GRIST_SESSION_SECRET: replace-with-a-long-random-string
GRIST_DEFAULT_EMAIL: [email protected]
GRIST_SINGLE_ORG: home
GRIST_FORCE_LOGIN: "true"
GRIST_SANDBOX_FLAVOR: gvisor
volumes:
- ./persist:/persist
restart: unless-stopped
GRIST_DEFAULT_EMAIL becomes the owner of the site, GRIST_SINGLE_ORG keeps the multi-tenant machinery out of the way, and GRIST_FORCE_LOGIN turns off anonymous access, which is on by default and hands every visitor owner rights to your documents. Do not skip that one.
Formulas are Python, and that is not a gimmick
A formula column is written as Python evaluated per row, with $Column for the row's own fields and record references that follow relations. A line-item table with a reference column to Products gets its price with $Product.Price, an invoice total is SUM(LineItems.lookupRecords(Invoice=$id).Amount), and anything the standard library can express, from date arithmetic to regular expressions, is fair game. Trigger formulas run once on record creation or when a chosen column changes, which is how you get created_at stamps and computed slugs that do not recalculate under you.
Because that is arbitrary code from any editor of the document, Grist runs formulas in a sandbox, and GRIST_SANDBOX_FLAVOR=gvisor is the setting that makes it real; the image ships gVisor and it works on ordinary x86 Docker. An unsandboxed flavour exists for hosts where gVisor cannot run, and it means anyone who can edit a document can run Python on your server. Treat that as a reason to find a host where gVisor works.
Authentication is the decision that takes the hour
Grist does not ship a login form. With GRIST_FORCE_LOGIN on and nothing else configured, nobody can get in, which surprises people on day 1. There are 3 sane routes. The lightest is forward auth from a reverse proxy: set GRIST_FORWARD_AUTH_HEADER=X-Forwarded-User and let Authelia or Authentik in front of the proxy decide who is who, a pattern the Authentik vs Authelia piece walks through. The cleanest is OIDC, configured with GRIST_OIDC_IDP_ISSUER, GRIST_OIDC_IDP_CLIENT_ID and GRIST_OIDC_IDP_CLIENT_SECRET against the same identity provider. SAML is there for organisations that already have it. A household with one user can even leave GRIST_FORCE_LOGIN off behind a Tailscale-only network and accept that everyone on the tailnet is the owner, as long as they understand that is what they chose.
Access rules turn a sheet into an application
Rules are written per table, per column or per row against user attributes and the record, so user.Email == rec.Owner on a Tasks table means each person sees only their own rows while the owner sees all, and a Salary column can be readable by user.Access == "owners" only. Add Grist Forms, which publish a table as a public data-entry page, plus custom widgets for maps, calendars and markdown, and a document becomes a small internal tool: an inventory with per-department views, a client tracker with a submission form, a grant pipeline with a Gantt-ish calendar. The REST API and per-document webhooks let n8n or a script read and write rows, so it also serves as the "database with a UI" behind automations.
Against NocoDB and Baserow
NocoDB is the right tool when the data already lives in a Postgres or MySQL database and you want a grid over it; Grist owns its data and would need an import. Baserow is the closest Airtable look-alike for a team that wants the familiar interface on a Postgres backend, and it is friendlier for non-technical users adding fields. Grist wins the moment you need computed logic, cross-table lookups or per-user visibility, which is the point where the other two hand you a plugin or a shrug. The wider choice, and what Airtable refugees actually lose, is in the Airtable alternatives page.
What I'd do
Run the compose file above with gVisor sandboxing, put it behind a proxy with forward auth from whichever identity provider you already run, and rsync /persist nightly. Build the first document as a real relation, Clients referencing Invoices referencing LineItems, rather than one flat sheet, because that is where Grist earns its keep. For a solo user on a tailnet it is 20 minutes of work; for a small team the hour on authentication is the whole cost, and after it you have an Airtable that costs $0 per seat and keeps its data in a file you can read with any SQLite client.
Compare Grist
7 head-to-head comparisons.
Similar office suites apps
Reveal.js
Office SuitesHTML Presentation Framework
Replaces Google Slides, Office 365
tldraw
Office SuitesInfinite canvas SDK for collaborative whiteboards
Replaces Miro, FigJam
drawDB
Office SuitesBrowser-based database schema design and ER diagram tool
Replaces dbdiagram.io, Lucidchart
Handsontable
Office SuitesJavaScript data grid component with spreadsheet-like editing
Replaces Google Sheets, Excel Online
Teable
Office SuitesPostgres-based no-code database and spreadsheet
Replaces Airtable
ConvertX
Office SuitesSelf-hosted online file converter supporting over a thousand formats
Replaces CloudConvert, Zamzar