Should I vibe code
Build a small hosted database app with pages, forms, and role-based views
Softr and NocoDB sit on a database that outlives them. Knack is the database. There is no other copy.
?
Their verdict, the Starter 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
The difference between this and the other no-code entries is where the data lives. Softr sits on an Airtable base and NocoDB attaches to a Postgres you already run, so in both cases there is a source of truth that survives the app. Knack is the source of truth. Objects, connections, records and the screens over them are one artefact, which means the thing you build in a few evenings quietly becomes the only copy of how a business operates — the job list, the member register, the equipment log, the class roster. It works, and it keeps working, and that is the mechanism: an app that never breaks accumulates responsibility. Then somebody who is not you needs a field added, or wants a text column to hold numbers so it sorts properly, and a schema change gets applied to live operational data by a person with no concept of a migration, at four in the afternoon, with no snapshot in front of it. Layer on role-based views enforced in the template rather than the query, an API you generated but never authorised properly, and a restore procedure nobody has run, and you have a system of record with all the obligations of one and none of the discipline.
What actually breaks
not "if". the specific failures.
- A field-type change, which is a destructive migration wearing a dropdown. Long text narrowed to short text truncates; text to number turns anything unparseable into null; and both happen inside a transaction that reports success
- The CSV import, where a column of order references like 0012 becomes 12, a European date is read as American, and a re-import intended to add rows updates matching ones instead
- Role-based views, when the role is checked in the page template but not in the query behind it — the fields are hidden and the JSON response still contains them
- The generated API, which exists the moment you build a front end and is almost never given the same authorisation rules as the screens, so the mobile-friendly endpoint returns what the web page carefully hid
- Deletes, because operational data has referential meaning: removing a customer with jobs attached either orphans the jobs or cascades away six months of history, and there is no undo on either
- Backups, in the only way that matters — they exist, they run, and nobody has ever restored one, so the first restore is attempted under pressure with a business standing still
- Formula and rollup fields, which recompute over historical rows when you change them, so last year's totals silently become this year's formula applied to last year's data
- Concurrent edits, since two staff on the same record in a form-based app produce last-write-wins, and the loser's change disappears without a message
- Growth, because unlimited users is exactly how a tool for four people ends up with a hundred logins and a customer-facing portal nobody designed for
Nothing alerts, because nothing failed. On Thursday the operations lead asked for the Notes column on jobs to be tidied up so it would fit in the table view, and you obliged — long text to short text, one change in the schema editor, applied in about four seconds. Postgres did precisely what it was told and truncated every value over 255 characters, in place. What was in those fields was the useful part: what the engineer found on site, why the second visit was needed, which parts were ordered, who authorised the extra cost. You notice on the following Tuesday because a customer disputes an invoice and the note that would settle it now stops mid-sentence. The backups are nightly, which would be fine, except the earliest one still on the retention plan is from Friday morning and this happened on Thursday afternoon. Four years of field notes, on eleven thousand jobs, are gone in the boring way: not stolen, not corrupted, just shortened.
Is that you?
the verdict is a default, not a law
- It is a tool for you and a couple of colleagues, and the data would be annoying to lose rather than ruinous
- The database has a real source of truth somewhere else and this is a view over it
- The schema is fixed and only you change it, through a migration in version control that you can read back later
- Nobody outside the company logs in, so there is no tenant boundary to get wrong
- You have restored a backup, on purpose, into a scratch environment, and timed it
- The business would stop if this app were unavailable for a day, which is the honest test of whether it is a side project
- Someone who does not write migrations can change a field's type or delete a column
- Customers or members log in to see their own records, because that is a multi-tenant application and it needs a tenant boundary in the query
- The only copy of anything lives here
- You cannot say when the last successful restore test happened
If you build it anyway
the checklist, then the prompt that enforces it
- Write the backup and the restore before the first screen. Automated snapshots, off-site, with point-in-time recovery, and a restore you have actually performed and timed. In an app that is its own source of truth this is not operations hygiene, it is the product.
- Take a snapshot immediately before any schema change, automatically, and refuse to apply destructive column alterations without one. Narrowing a type or dropping a column is a data deletion with a friendly name.
- Never let a non-engineer change types or drop fields. Adding a field is safe; changing one is a migration, and migrations belong in version control with a rollback path.
- Soft-delete everything user-facing and keep the tombstones. Operational records have history attached, and a hard delete takes the history with it.
- Enforce permissions in the query, not the template. Every read applies the role filter server-side and the negative test — request another role's record by ID, assert nothing comes back — runs in CI.
- Give the API the same authorisation as the pages. It is a separate surface with a separate code path, and it is the one that gets forgotten.
- Make imports a two-step operation: dry run showing exactly what would be created, updated and skipped, then apply. Force explicit types on every column rather than letting the parser guess.
- Add optimistic concurrency to edit forms — a version stamp on the record and a real conflict message — before the second person starts using it.
- Version formula and rollup definitions and keep the historical value alongside the computed one, so changing a calculation does not rewrite the past.
I am building a small operational database app: custom objects, relationships,
forms, tables and role-based views, on a database that is the only copy of this
data. Assume it becomes the system of record for a real business. Build in this
order and refuse to reorder it.
1. Backups first, before any feature. Automated snapshots, off-site, with
point-in-time recovery. Then write me the restore runbook and walk me through
performing it once into a scratch database. Tell me how long it took.
2. Then destructive-change protection. Any schema operation that can lose data —
narrowing a type, changing a type, dropping a column, dropping a table — takes
an automatic snapshot first and requires an explicit confirmation. If I ask for
a UI that lets a non-engineer change a field type, push back and explain
truncation with an example.
3. Then deletion semantics: soft-delete with tombstones for every user-facing
record, and an explicit decision for each relationship about restrict, cascade
or orphan. Show me that decision as a table before you write it.
4. Then authorisation, in the query and not the template. One function reads
records, it takes the authenticated user and applies the role filter itself,
and every route calls it. Write the negative test first: as one role, request
another role's record by ID and assert an empty response. Put it in CI.
5. The API gets the identical authorisation rules as the pages, from the same
code path. Say out loud that this is the surface most likely to leak.
6. Then imports: dry-run mode that reports created, updated and skipped counts
before anything is written, explicit column types, no type inference, and a
documented match key. Never let an import silently update.
7. Then concurrency: a version stamp on every editable record and a real conflict
message. Not last-write-wins.
8. Audit log next — who changed which record, which field, from what to what, and
when. Keep it separate from the records it describes.
9. Formula fields store their definition version and the computed value at write
time. Changing a formula must not rewrite history.
10. Out of scope until I ask: customer-facing portals, file uploads, payments and
public forms. If I ask for customer logins, stop and tell me that turns this
into multi-tenant software, and that $59 a month for a platform with a tested
restore and someone else's permission model is the cheaper answer.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
When the app stops being convenient and starts being load-bearing — when someone else's day depends on it, or when the record it holds is the only one. $59 a month buys the parts you would otherwise be improvising: snapshots and a restore path that other people have used in anger, a permission model tested by strangers, an import that dry-runs, and an audit trail. Watch the meter, though: every tier has unlimited users and a record cap, so 20,000 records on Starter and 50,000 on Pro is what actually sets your bill, not the size of your team.
$59/mo is cheaper than your weekend.
This is the entry where the exit plan has to exist on day one, because the app is the data. Get a scheduled export of every object as CSV plus the schema as JSON, landing somewhere that is not the same account as the database, and check that the export actually contains attachments and relationship keys rather than display labels — an export that names the linked record instead of identifying it cannot be reassembled. Test the round trip once: import yesterday's export into an empty instance and see what is missing. Moving to Knack or another platform later is then a mapping exercise rather than an archaeology one, and the same artefact doubles as your disaster recovery. If you never build the export, the exit plan is the phrase "we still have the database", said hopefully.
Actively developed open-source no-code database interface, self-hostable over a Postgres or MySQL you control.
Open-source low-code platform for internal apps, with a real role and permission model rather than a hidden column.
Questions
Why is this rated worse than NocoDB, which points at my production database?
They fail in opposite directions. NocoDB's hazard is that a grid with write access sits on a database that other systems depend on — you can damage something important that already existed. Knack's hazard is that nothing existed before: the app creates the data, holds the only copy, and every mistake is unrecoverable by definition. NocoDB users at least have a DBA-shaped person somewhere. A Knack-shaped build usually has nobody who has ever restored anything.
Everything is in Postgres. Isn't that already durable?
Postgres is extremely good at not losing data it was not told to remove. It has no opinion about a migration that truncates a column, an import that overwrites the wrong rows, or a cascade delete that was correct SQL and a terrible idea. Durability protects you from hardware; snapshots and a tested restore protect you from yourself, and the second failure mode is the one that actually happens.
My views hide the fields other roles shouldn't see. Isn't that enough?
Only if the filtering happens in the query. The common generated shape fetches the record and hides fields in the template, so the API response still contains everything and the network tab shows it. Test it by opening devtools as a restricted user and reading the JSON. If the value is in there, it is not hidden, it is styled.
It's only for internal staff. Does that change the verdict?
It improves it considerably — that is most of the shipItIf list. Internal-only removes the tenant boundary, which is the most-broken thing in this category. What it does not remove is the data-loss story, because the app is still the only copy of how the business runs, and the person who asks for a field to be changed is the same colleague you built it for.
- GDPR Art. 5 — principles relating to processing of personal data (EU)
- GDPR Art. 32 — security of processing (EU)
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.
A client portal is multi-tenant software. If the filter is a URL parameter, so is everyone else's data.
An agent will happily hand you a spreadsheet with UPDATE on production. Postgres has no undo button.
The open-source one already exists. Self-host that instead of rebuilding it.
last reviewed 2026-08-05 · verdict is editorial and unsponsored · shared entry data from canivibecodeit under MIT · not legal advice