---
name: no-code-app
description: "Use when building an app on a no-code/low-code platform (Bubble, Softr, Glide, with Airtable/Xano backends) — picking the tool, modeling the data, taming usage/cost metering, or planning the exit before lock-in. Triggers: 'build a CRM without code', 'Bubble or Glide for my MVP', 'monta una app sin codi per reserves', 'my Bubble bill suddenly exploded' (workload-unit metering), 'Glide updates overage', 'how do I avoid getting locked into a no-code tool', 'when should I stop and write real code'. NOT a coded web app (that is nextjs)."
tags: [no-code, low-code, bubble, glide, softr, app-builder, mvp]
recommends: [nextjs, shopify, wordpress, automation-flows, spreadsheet-ops, notion-connector, stripe]
origin: risco
---

# No-code app

You are deciding whether to build an app on a visual platform, which platform, how to model it, and where the wall is. No-code is not "the easy way" — it is a trade: you buy speed-to-first-user and pay it back in logic ceilings and metered cost. Your job is to make that trade with eyes open.

## The one rule

Decide the exit before you build the entrance.

- No-code wins on **speed-to-first-user** — a working app in days, no deploy pipeline. That is the only thing it reliably wins.
- It dies on **deep conditional logic** and on **scale economics** — many-branch workflows get unmaintainable, and metering turns a $29 bill into a $400 one without warning.
- ~25-30% of no-code projects get rewritten when they outgrow the tool, at $50K-$250K. ~68% of platforms offer no code export. If you cannot describe how you would leave, you are not building an MVP — you are building a hostage.

## Step 0: is no-code even the right tool?

Run this gate before touching any builder. If any line is a clear yes, route out — do not rationalize staying.

| If the user really wants... | Stop and go to |
| --- | --- |
| A hand-written app, full control over code | [../nextjs/SKILL.md](../nextjs/SKILL.md) (or react) |
| A commerce storefront, products + checkout | `shopify` |
| A content site / blog / CMS | `wordpress` |
| To wire SaaS tools together, no app UI | [../automation-flows/SKILL.md](../automation-flows/SKILL.md) |
| A spreadsheet as the deliverable itself | [../spreadsheet-ops/SKILL.md](../spreadsheet-ops/SKILL.md) |
| A Notion workspace, not a published app | [../notion-connector/SKILL.md](../notion-connector/SKILL.md) |

No-code is the right tool when ALL hold: there is a real app UI (screens + data + logic), the logic is mostly CRUD + a handful of rules, time-to-launch matters more than scale today, and you accept the platform owns your runtime. If logic is the heart of the product (pricing engine, matching algorithm, real-time anything), no-code is wrong even if the UI is simple — write code.

## Pick the platform

Match the platform to the **app shape**, then to the **billing model** you will have to defend in six months. Why this order: the billing model, not the feature list, is what kills no-code projects.

| App shape | Platform | Bills on | Why |
| --- | --- | --- | --- |
| Internal tool / client portal over existing data | **Softr** | Flat rate per workspace | No per-write metering, no charge for internal editors → predictable as you grow |
| Customer-facing, simple, mobile-feel | **Glide** | "Updates" (data writes) | Fast to ship; cost scales with write volume, and rows are capped per plan (a standard source tops out far below Glide's own tables) — watch both |
| Complex custom SaaS, heavy logic, custom workflows | **Bubble** | Workload Units (WU) | Most powerful builder; every query/workflow/API call burns WU, and tier allotments are small (Starter ~175K WU, Growth ~250K — only ~1.4x, not the 4x some stale write-ups claim) → cost is a function of usage, not seats |

Rules:
- **Default to Softr for anything that is "a nice front-end over a table."** Flat-rate billing means a usage spike does not become a surprise invoice.
- **Reach for Bubble only when the logic genuinely needs it.** Bubble can do almost anything; that power is exactly why its WU bill is hard to predict. If you pick Bubble for a simple portal you are overpaying in money and complexity.
- **If you find yourself fighting the builder to express logic, that is the signal to stop** and reconsider [../nextjs/SKILL.md](../nextjs/SKILL.md). The builder fighting back is the migration cliff sending a postcard.

Exact tiers and numbers change — see [references/platform-limits.md](references/platform-limits.md). Do not hardcode prices into your design; design against the *metering model*.

## Model the data first

Tables and relations come before a single screen. Why: screens are cheap to rebuild, a wrong data model poisons every workflow and every cost estimate on top of it.

Pick the backend by **logic complexity**, not by familiarity:

| Backend | What it is | Use when | Watch out |
| --- | --- | --- | --- |
| Platform-native DB | Built into Bubble/Glide/Softr | Simple apps, one source of truth | Locked to the platform |
| Airtable | Relational DB with a spreadsheet UI | Simple read/create, admin data entry | ~50K records/base cap, slow API |
| Xano | Full backend (PostgreSQL + visual API builder) | Complex logic, performance, security | More setup; it is a real backend |

The hybrid pattern that scales: **Airtable for human data entry/admin, Xano for API logic + performance + security.**

Field-type and relation discipline:
- Normalize. One entity = one table. A `bookings` row links to `customers` and `classes` by relation, it does not copy the customer's name and email into every booking.
- Give every field its real type (date, number, single-select), not "text for everything." Wrong types make filters and aggregations expensive or impossible later.
- Watch the **50K-record/base cap on Airtable** and the fact that on Bubble every relation traversal in a workflow is WU you pay for.

Bad → Good:

```text
Bad  — one giant "Records" table, 40 columns, status in a text field,
       customer name + email + class title all duplicated per row.
       => filtering is slow, a rename means editing every row, WU/updates balloon.

Good — customers | classes | bookings(customer→, class→, date, status:single-select)
       => rename once, filter by relation, aggregate cleanly, predictable cost.
```

Sketch the model in plain text before you build it:

```yaml
customers: { id, name, email, phone }
classes:   { id, title, starts_at, capacity, instructor }
bookings:  { id, customer: ->customers, class: ->classes, status: [pending|paid|cancelled], created_at }
payments:  { id, booking: ->bookings, amount, provider_ref }   # via stripe
```

## Build logic without footguns

The metering model punishes the obvious-but-wrong way of doing things. Build defensively.

- **Keep workflows shallow.** A 6-level nested conditional in a visual editor is unreadable and un-debuggable. If logic gets that deep, it belongs in code (Xano function or a real backend), not in the builder canvas.
- **Batch writes; never loop an API call per row.** A workflow that fires one external API call per record across 2,000 rows is 2,000 metered operations — this is the #1 cause of an exploded Bubble WU bill and Glide update overage. Batch, or move the loop server-side.
- **Validate server-side, not just in the UI.** Client-side-only validation in a no-code app is trivially bypassed; enforce rules in the backend (Bubble backend workflow, Xano endpoint) and gate writes with privacy/permission rules.
- **Push expensive aggregation to scheduled jobs**, not to every page load. Recomputing a dashboard on each view multiplies reads by traffic.

Bad → Good:

```text
Bad  — On booking confirmed: loop over all 2,000 customers, call email API per row.
       => 2,000 metered ops every run; WU/update bill spikes; rate limits hit.

Good — On booking confirmed: write one row; a scheduled batch job sends queued emails.
       => one metered write per booking; sending is amortized and rate-safe.
```

## Know your limits and the cost ceiling

The full 2026 tier/metering/record-cap table and worked cost examples live in [references/platform-limits.md](references/platform-limits.md). Operating rules:

- **Estimate cost from the metering model, not the sticker price.** Bubble: count WU ≈ queries + workflow steps + API calls per user action, times expected actions/month. Glide: count data writes (updates) per user per month. A free or Starter tier that looks fine at demo traffic is the trap.
- **Load-test at 10x expected rows, early.** A Bubble app that is snappy at 100 records can crawl at 10,000. Find the wall before your users do, not after.
- **Know the hard caps**: Airtable ~50K records/base; per-tier app/user/row limits on every platform. Design so you do not silently hit one in month three.
- **Watch the overage meters**: Bubble warns by email at 75% and 100% of your WU allotment, then charges overage. Wire those warnings to a human who can react.

## Plan the exit

This is the section everyone skips and everyone regrets. Do it on day 1.

1. **Export your data on day 1 and on a schedule.** Confirm the platform actually lets you export records (~68% give you no code export — data export is the minimum you must verify).
2. **Keep the data model portable.** Clean tables + relations (the model above) map onto Postgres/Prisma directly. A giant denormalized table does not.
3. **Know your migrate-off triggers** and watch for them:
   - Logic outgrows the canvas — many-branch conditionals, custom algorithms.
   - Performance — it crawls at real row counts (the 10K-row test).
   - Cost — the metered bill crosses what a real backend + hosting would cost.
4. **Price the rewrite honestly.** Outgrowing the tool means a $50K-$250K rebuild. Knowing that number is what lets you decide *now* whether to start in code via [../nextjs/SKILL.md](../nextjs/SKILL.md) instead.

When two of those triggers fire, stop adding features and start the migration plan — do not keep pouring work into a runtime you are about to leave.

## Anti-patterns

| Bad | Good | Why |
| --- | --- | --- |
| Reaching for Bubble because "no-code is faster" | Run Step 0 gate first | Coded apps/stores/blogs route to nextjs/shopify/wordpress |
| Building screens, then bolting on data | Model tables + relations first | Wrong model poisons every workflow and cost estimate |
| One giant table, 40 columns, text-typed everything | Normalized tables linked by relation | Cheap renames, fast filters, predictable metering |
| Airtable for complex logic + scale | Xano (or hybrid: Airtable entry + Xano logic) | Airtable ~50K cap + slow API; Xano is a real backend |
| Per-row API call in a workflow loop | Batch writes / scheduled jobs | #1 cause of WU/update bill explosions |
| Client-side-only validation | Enforce rules server-side + permission gates | UI validation is trivially bypassed |
| Pricing off the monthly sticker | Estimate from the metering model | WU/updates scale with usage, not the headline price |
| Testing only at demo scale (100 rows) | Load-test at 10x expected rows early | Snappy at 100 can crawl at 10,000 |
| No export plan, hope you never leave | Export day 1, keep model portable | 68% offer no code export; rewrite is $50K-$250K |
| Picking Bubble for a simple internal portal | Softr (flat-rate) for portals over data | Predictable cost, no per-write surprise |

## References

- [references/platform-limits.md](references/platform-limits.md) — 2026 pricing/metering/record-cap cheatsheet (Bubble WU tiers, Glide updates, Softr flat tiers), backend comparison (native/Airtable/Xano), cost-estimation worked examples, and the migrate-off trigger list, with sources and access dates.

Payments in any of these flows: see [../stripe/SKILL.md](../stripe/SKILL.md).
