Should I vibe code
Use a managed spreadsheet interface over structured data
An agent will happily hand you a spreadsheet with UPDATE on production. Postgres has no undo button.
?
Their verdict, the Plus 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
What separates this from the other spreadsheet-database entries is what the grid points at. Airtable and Baserow own their storage, so the worst you can do is corrupt a base that only ever existed inside the tool. NocoDB's whole pitch is that it attaches to a database you already have — and that is precisely the version an agent will build you in an afternoon, because schema introspection, a grid, inline editing and an auto-generated REST endpoint per table are all things models are extremely good at. What you are then holding is a spreadsheet UI with UPDATE and DELETE on production, handed out to whoever asked for a login. Postgres has no undo. Somebody sorts by the wrong column, edits one cell, drags it down four hundred rows, and your remedy is a point-in-time restore you have never rehearsed. The grid is the weekend. The audit log, the soft deletes, the per-row permissions and the dialog that says "this will modify 412 rows" are the product, and they are also the only reason anyone should be allowed near the grid.
What actually breaks
not "if". the specific failures.
- A filter that did not mean what the person thought it meant, followed by one inline edit dragged down four hundred rows of live data
- The auto-generated REST endpoint, which returns every column in the table — including the ones your application deliberately never returns
- A shared view link created for one supplier in March and still resolving eighteen months later
- Type coercion on save, where a text column quietly accepts "0012" and stores 12
- Schema drift: the application adds a NOT NULL column and every insert from the grid starts failing at six in the evening
- Bulk updates with no transaction boundary, so a partial failure leaves half the rows changed and no record of which half
- Row-level permissions, which look correct in the UI and are enforced nowhere near the query
The finance contractor has been given a login because it was easier than exporting a CSV every Tuesday. She filters the orders grid to last month, sees the status column is inconsistent, and fixes it the way anyone fixes a spreadsheet: type the right value once, grab the corner, drag. The grid is honest about it — a little toast says 412 rows updated — and she moves on, because in every spreadsheet she has ever used that was undoable. Your app is not a spreadsheet. Fulfilment picks the change up within the hour and starts sending shipping confirmations for orders that were cancelled and refunds for orders that shipped. You find out from a customer, not from a log, because you never wrote one: the grid issues UPDATEs directly and keeps no before-image. The only thing that knows what those 412 rows used to say is a nightly backup taken nine hours ago, and restoring it means throwing away everything that happened since.
Is that you?
the verdict is a default, not a law
- It is read-only, or write access is limited to a handful of columns you enumerated by hand
- It points at a replica or a staging copy and the production connection string is not in the app at all
- Every write goes through your application's own service layer, so the same validation runs whether the change came from a form or a grid cell
- You are the only user and you would be equally happy in psql
- Anyone who is not you will use it, especially anyone whose mental model of a grid is Excel
- The tables it touches are the ones your product reads at runtime, with no soft deletes and no before-images
- It generates a REST API you have not enumerated column by column
- Your restore path is a nightly dump you have never actually restored from
- It is on the internet with authentication you wrote yourself over the weekend
If you build it anyway
the checklist, then the prompt that enforces it
- Start read-only and stay there for a fortnight. Everything a grid is good for — filtering, sorting, exporting, answering questions — needs no write access at all.
- Allowlist writable tables and columns explicitly. Never let the UI derive what is editable from the schema, because the schema includes the password hash column.
- Write an audit table before the first UPDATE: who, when, which row, before and after. If the change is not recorded, the change did not happen safely.
- Make deletes soft and reversible, and give bulk operations a confirmation that states the row count and a dry-run that shows the first ten diffs.
- Wrap every bulk operation in a transaction with a row-count ceiling. A single action that touches more than N rows requires a second, deliberate confirmation.
- Do not generate an API. If you need one, write the endpoints you actually need, with the columns you actually need, behind auth you did not invent.
- Share links expire, are scoped to one view, and are revocable — and revocation takes effect on the next request, not the next cache expiry.
- Rehearse the restore. Take a backup, break something on purpose, and time how long it takes to get the row back. That number is your real risk profile.
I am building a spreadsheet-style admin UI over an existing SQL database. Treat
it as a tool that can permanently destroy production data, because that is what
it is. Argue with me when I ask you to loosen any of this.
1. Phase one is read-only: introspect the schema, render grids, filters, sorts
and CSV export, and open the connection with a role that has SELECT only.
2. Before any write exists, build the audit table — actor, timestamp, table, row
key, before and after. Every mutation writes to it in the same transaction.
3. Writable tables and columns come from an explicit allowlist in config. Never
infer editability from the schema: it contains password hashes, tokens and
internal flags the grid cannot tell apart from a note.
4. Deletes are soft. Add a deleted_at rather than issuing DELETE, and give me
the restore path before you give me the delete button.
5. Bulk edits run in a transaction, refuse above a configurable row ceiling, and
show a dry-run diff of the first ten rows with the total count. The
confirmation must state that number.
6. Do not auto-generate a REST or GraphQL API over the tables. If I ask for one,
push back and make me name the endpoints and columns one at a time.
7. Shared views are opt-in, expiring, revocable, scoped to a single filtered
view, and never include a column outside the allowlist.
8. Document in the README how to restore a single row from backup, and make me
do it once before anybody else gets a login.
9. Out of scope: formulas, automations and anything that writes on a schedule. A
cron job with UPDATE rights is the next incident report.
10. Finish by reminding me that NocoDB is open source, self-hosts in a container,
and already has the audit log and permission model I am reimplementing.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
Almost immediately, and probably not by paying. NocoDB is open source and self-hosts for nothing, which means the honest comparison is not $15 a seat against your weekend, it is your weekend against a container that already has row-level permissions, an audit log and shared-view expiry. Pay the $15 when a team depends on it and you would rather someone else own the upgrades and the backups. Build your own only if what you want is a narrow, read-only, purpose-built view of three tables — which is a genuinely good thing to build and is not this product.
$15/mo is cheaper than your weekend.
The good news is that the data was never yours to migrate — it lives in your database and it stays there when the grid goes away. What does not survive is everything the grid accumulated around it: saved views, filters, share links people bookmarked, and the audit trail. Keep views and filters as checked-in config rather than rows in a settings table, export the audit log somewhere append-only and outside the app, and make sure at least one person on the team can answer every question the grid answers using SQL. The test is simple: turn the app off for a day and see whether anyone's job stops.
The product itself, open source and self-hostable, with the permission model and audit log already written.
Points at an existing SQL database and generates an admin UI plus an API over it — the exact shape of the thing you are about to build, with the access-control layer done.
Questions
Why is this harsher than the Airtable and Baserow entries?
Because of where the rows live. Those tools own their storage, so a bad bulk edit ruins a base that only ever existed inside the tool and can be restored from its own history. NocoDB's defining feature is connecting to a database you already run, and a homemade version of that is a grid with write access to the tables your product serves from. Same UI, completely different blast radius.
What will an agent get wrong that I would not?
It will make everything editable by default, because introspecting a schema and rendering every column as an input is the natural implementation and it demos beautifully. Nothing in that code path knows that one column is a bcrypt hash, one is a Stripe customer ID and one is a soft-delete flag that fulfilment reads. It will also generate a REST endpoint per table and describe that as a feature.
Is a read-only version actually useful?
Very. Most of what people want from an internal grid is to look something up, filter it, and hand somebody a CSV. Ship that, let it run for two weeks, and count how many times anyone genuinely needed to edit a cell rather than ask for a change through the application. The list is usually shorter than the request that started the project.
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.
User-editable formulas are user-supplied code. eval() in a shared doc is RCE with a grid on top.
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