Should I vibe code
Combine spreadsheet formulas with relational records in a small self-hosted workspace
User-editable formulas are user-supplied code. eval() in a shared doc is RCE with a grid on top.
?
Their verdict, the Pro price and the build-time estimate come from their entry, MIT-licensed. Checked 2026-08-04.
?
Our verdict, the regret score and everything below it. Editorial and unsponsored — nobody can pay to be moved.
The honest answer
why the verdict is what it is
A grid over SQLite is a weekend and it feels like real progress, right up until the first formula. Grist's engine is Python evaluated per cell with a dependency graph behind it, recalculating only what changed — and there are two ways to reimplement that. One is a toy expression language nobody will accept because it cannot do the thing they wanted. The other is eval, which turns a shared document into a remote code execution service with a spreadsheet on the front. Meanwhile grist-core is Apache-2.0 and starts in one container.
What actually breaks
not "if". the specific failures.
- Formulas, the moment somebody wants one that references another table
- Recalculation order, because a spreadsheet is a dependency graph and "recompute everything on save" stops being viable somewhere around ten thousand rows
- Undo, once two people are editing at the same time — the operation that made your app feel like a spreadsheet is the one with a decade of literature behind it
- Access rules at cell level, which is what Grist actually sells and which is a query rewriter, not an if-statement in a controller
- The document that quietly becomes the system of record for the whole team, backed up by nothing
Is that you?
the verdict is a default, not a law
- It is a table with typed columns and a couple of views, and the only person writing formulas is you
- The data is a copy of something that still exists somewhere else
- You are exploring an idea and the throwaway is genuinely going to be thrown away
- Other people write formulas in it
- It has become the only copy of something a business decision depends on
- You need per-row or per-cell permissions
- Nobody has ever restored from one of your backups
If you build it anyway
the checklist, then the prompt that enforces it
- Do not eval user formulas in your process. If formulas are required, run them in a sandboxed interpreter with no filesystem, no network and a CPU limit — or restrict them to an expression language you parse yourself and refuse everything else.
- Keep the data in plain SQLite or Postgres with real column types, so any tool can read it the day yours stops running.
- Backups before features: a snapshot per document per day, offsite, and a restore you have actually performed at least once.
- Every schema change is a reversible migration file. "Change this column's type" is where the only copy of the data goes.
- Export to CSV per table, with an importer that round-trips it. The day this becomes the system of record, you want the door already open.
- Cap document size and warn early. Ten thousand rows rendered into the DOM is a great demo and an unusable tool.
I am building a spreadsheet-database hybrid: typed columns, linked tables,
views, and eventually formulas. The data will outlive my interest in the code,
so apply these and push back if I ask you to break them.
1. Before any UI, decide storage: plain SQLite or Postgres, real column types,
a schema a stranger could read. No JSON blob holding the whole document.
2. Build export second: CSV per table plus the schema, and an importer that
round-trips its own output. Prove the round trip with a test.
3. Then backups: a daily snapshot per document, written somewhere that is not
the app's own disk, with a restore command. Make me run the restore once
before we go further.
4. Every schema change ships as a reversible migration file. Never mutate a
column type in place without writing the old values somewhere first.
5. When I ask for formulas, stop and give me the choice explicitly: a small
expression language you parse and evaluate yourself, or a real interpreter
in a sandbox. Do not reach for eval, exec or new Function.
6. If we sandbox, it gets no filesystem, no network, no subprocess, a CPU
limit and a memory limit, and it runs out of process. Tell me what happens
when a formula loops forever.
7. Formulas are per-cell code written by whoever can edit the document. State
that plainly in the README, and treat edit access as equivalent to code
execution access when designing permissions.
8. Recalculate from a dependency graph, not by recomputing every cell. Detect
cycles and surface them as an error in the cell rather than a hang.
9. Do not promise real-time collaboration or multi-user undo. If I ask, tell me
what operational transform or CRDT would cost here, and offer document
locking instead.
10. Virtualise the grid and cap rows per view. A DOM with ten thousand rows in
it is the demo everyone builds and nobody uses twice.
11. Before I invest a second weekend, remind me that grist-core is Apache-2.0
and runs in one container, and ask what I get that it does not already do.That one keeps you out of trouble. For the prompt that actually builds it, canivibecodeit.com has one.
their build prompt ↗Or don’t build it
the boring option, and the way back out
Sooner than usual, and not necessarily for money: grist-core is Apache-2.0, self-hosts in a container, and hands you the formula engine, the access rules and the undo model for nothing. $8 a user adds backups and somebody else's on-call. Writing a third implementation of this is the one option here with no upside.
$8/mo is cheaper than your weekend.
Everything worth keeping is rows, so the exit is a CSV per table plus the schema, written on a schedule to somewhere that is not the app's disk. Write the formulas out too — as text, in a column beside the values they produced — because a formula whose only interpreter was your app is a meaning that disappears with the code. Do that and quitting costs you a UI, not a system of record.
Grist itself, Apache-2.0 and self-hostable, formula engine and access rules included. If you want Grist, run this — that is the whole recommendation.
Active open-source no-code database interface that puts a grid over an existing Postgres or MySQL, which is often the actual need.
Questions
Why not just use SQLite and a table component?
Do exactly that — it is the SHIP IT case, it takes a weekend, and for a great many internal tools it is the right answer. The demo-only line starts at formulas, because that is where you stop building an app and start building a language runtime.
Is eval really so bad if it is only my own team?
It is your team plus anyone who gets hold of a session, plus whatever a mistaken paste does. A formula that can open a socket or read a file is a very short path from "shared document" to "shell on the server that holds every document". If formulas must exist, they run in a sandbox out of process, or they do not run.
What does Grist do that a normal no-code database doesn't?
Real Python formulas with the standard library available, access rules that go down to the cell, and a document that is a file you can download. Those three are also precisely the parts that are hard to rebuild — which is the argument for running grist-core rather than reimplementing it.
Every week, someone ships something they shouldn’t have.
New verdicts, the worst thing that landed in the trap, and the occasional incident report. No other email, ever.
The open-source one already exists. Self-host that instead of rebuilding it.
An agent will happily hand you a spreadsheet with UPDATE on production. Postgres has no undo button.
A cell that calls an API on a schedule isn't a cell. It's a cron job with somebody's refresh token inside it.
last reviewed 2026-08-04 · verdict is editorial and unsponsored · shared entry data from canivibecodeit under MIT · not legal advice