Supabase
If you've never heard of Supabase, that's fine. Most people haven't. By the end of this page, you'll know exactly what it is, why your app needs it, and how to set it up in about five minutes.
The 30-second version
- What it is: an online backend service for users, database records, files, and realtime features.
- Why you need it: every real app needs a place to remember things between sessions. Supabase is that place.
- How hard: five minutes, once. Sign up on supabase.com, copy a few short strings, paste them into Appsanic, done.
- What it costs: Supabase offers multiple plans and usage limits. Review its current pricing for your expected database, storage, bandwidth, and active-user load.
- Where it lives: in your name, in your own Supabase account. Not ours. You own it.
If that's enough for you, skip to How to connect Supabase below. Otherwise, keep reading. The next sections explain why apps need this kind of thing in the first place.
Why apps need something like Supabase (the no-jargon version)
Imagine the simplest possible app: a button that, when you tap it, shows the time. That app is just screens. It doesn't have to remember anything between uses. Close it, open it tomorrow. Same buttons, same behaviour. No external services needed.
Now imagine a real app. Say, a habit tracker. The moment you tap "I drank water today," your app has to remember that. Tomorrow when you open the app, that tick has to still be there. Next week, when you check your streak, the app has to look back at the last seven days.
That memory has to live somewhere. It can't just live on your phone, because:
- If your phone dies, the memory dies with it.
- If you sign in from your tablet, the tablet doesn't know your phone's history.
- If you have friends who share the app, your habits have to be visible to them, and they're not on your phone.
So the memory has to live somewhere on the internet: somewhere your phone can reach, your friends' phones can reach, your tablet can reach. Some shared place every copy of the app can look at.
Supabase is that place. It's a free service that, once you sign up, gives your app a private spot on the internet where it can write down anything it needs to remember.
Without Supabase (or something like it), your app is a brochure: pretty screens, no real memory. With Supabase, your app is a real app, with users, with their data, with a history.
The four things Supabase gives you
It's not just memory. Supabase actually rolls up four useful things into one service:
1. A place to remember stuff (a database)
The main thing. Every kind of thing your app remembers (users, posts, messages, settings, anything) has a spot here.
What's "a database"? It's just a fancy word for a place that holds organised information. Picture a giant, very tidy filing cabinet. One drawer for users, one drawer for posts, one drawer for orders. Each drawer holds cards (rows) with the same kind of information on each. That's it.
2. Sign-in (also called "authentication")
The whole sign-up, sign-in, "forgot my password," "sign in with Google" experience. Supabase handles all of this. You don't build any of it from scratch. Appsanic taps into Supabase's sign-in system and your app gets a complete sign-in flow.
3. A place for files (file storage)
Photos, videos, voice notes, PDFs, anything users upload. They go into Supabase's file storage. Each user only has access to their own files, by default.
4. Live updates (also called "realtime")
When something changes (a new message, a friend ticks off a habit), every phone using your app sees it instantly. No "tap refresh to see new messages."
All four of those things, one service, one account. That's what makes Supabase special. Every other option requires you to plug in three or four different things.
Picture it this way
If your app is a coffee shop, Supabase is the back room:
- The front of house (your app): the counter, the menu boards, the chairs, the lighting. That's what customers see.
- The back room (Supabase): where the till records every transaction, where the staff sign in for their shifts, where the stock is stored, where the manager looks at yesterday's numbers.
Customers never go in the back room. They don't need to know it exists. But without it, the shop doesn't actually function. It's just a room with chairs.
You design what the front of house looks like in Appsanic. Supabase quietly runs the back room.
Why does Appsanic use Supabase specifically?
Reasonable question, since there are other options. The short version:
- It's free for ages. Most apps stay free until they have tens of thousands of users.
- It does four things in one. Other options cover one thing each. You'd have to plug in three or four separate services and remember which is which.
- You own it, and it's based on Postgres - the same database that powers some of the world's most serious products. Your project lives in your account, so you can move to any other Postgres tool any time. The next section covers this in full.
You own everything
This is worth saying twice because it's the most important thing about Supabase + Appsanic:
Your Supabase project lives in your own Supabase account. Not ours.
You sign up for Supabase yourself, in your name. Their bills come to you (which is free at the start). Appsanic gets a set of keys that lets it operate the project (open it, create things in it, save and read data), but the project itself is yours forever.
That means:
- If you cancel Appsanic tomorrow, your Supabase project keeps running.
- Your users keep using your app even if you stop using Appsanic.
- You can sign in to supabase.com directly any time and see exactly what's there.
- You can export everything to a file you control (Supabase has a one-click export).
- You can move to any other tool that speaks Postgres if you want.
No lock-in. No data ransom. You hold the keys.
How Appsanic and Supabase actually work together
When you describe a feature to the agent (say, "let users save favourite recipes", "add sign-in with email and password", or "let users upload a profile photo"), the agent always writes the app code and may also perform an eligible build-time Supabase action:
- Writes the app code: the screens, the buttons, the lists.
- Uses an approved server-side action when one is available and Account access is on. Anything high-risk, destructive, or unsupported stays manual, and the agent gives you explicit setup steps instead.
The agent says when it is about to use an account action. Its secret-redacted receipt appears in the connector's AI activity feed. Connection tests and credential changes are management events and do not appear there.
If you ever want to peek behind the scenes, click Supabase dashboard from inside your Appsanic project. Supabase opens in a separate session; sign in there if needed and verify you selected the connected project.
What the AI can do for you, in Supabase
Once you've connected Supabase, the agent can use the public URL and anon key in generated client code. Account access is a separate toggle, off until you opt in. Turning it on makes only the currently eligible server-side actions available; it is not blanket permission and does not guarantee every Supabase operation can run automatically. Toggle changes take effect on the next build.
Depending on the actions available in the current build, the agent may:
- configure a non-destructive storage resource;
- use another narrowly defined, schema-validated build action surfaced for the connection; or
- generate SQL, auth, function, policy, and deployment instructions for you to review and apply manually.
Current automatic Supabase setup is limited to the bounded storage-bucket action. SQL, policies, auth settings, redirects, and function deployment are always generated as complete review-first files or dashboard steps; Appsanic does not ask for an account-wide management token.
For social sign-in, email/security settings, SQL changes, and server functions, follow the exact setup path the build presents. If an operation is not exposed as an authorised action, the agent must not execute it by another route.
What the AI sees vs what stays server-side
This is the part people get wrong, so it's worth being precise. "Connected" means the build has a verified project connection. With Account access on, the model may request an eligible server-side action; the dispatcher still validates the job, project, connection, action, and input before trusted code can use a secret.
What the AI sees in its working context (and embeds in your app's code):
- Your Supabase project URL (the
https://abcd1234.supabase.coaddress). - Your Supabase public key (also called the anon key). This one is safe to bundle into your app's JavaScript bundle - Supabase designed it that way. Your data is protected by the privacy rules you set on each table, not by hiding this key. The AI bakes this value as a string directly into your
lib/supabase.ts(or equivalent) so the app boots and connects without any extra setup on your side.
What stays encrypted and never enters the model prompt:
- Your admin key (also called the service-role key). This bypasses every privacy rule. Appsanic stores it under AES-256-GCM encryption, never inserts it into the model prompt, and lets only authorised server-side connector code use it for eligible build-time operations.
Appsanic does not collect the project's JWT signing secret.
Why this split matters:
Public values can appear in generated client code. Secret values may be used only by authorised server-side connector code for an eligible action. Otherwise the agent gives you manual steps and the names of runtime secrets to configure directly in your deployed backend.
"Connected" proves the saved credential passed its connector test; it does not mean every optional permission or published-app runtime secret exists. If the build needs an optional field, it shows a connector card naming that field. If a deployed function needs a secret, add it directly to the function's secret manager.
Connecting Supabase to a project
This setup takes about five minutes and applies to the current project. Connect other projects separately so their databases and environments do not become linked accidentally.
Open the Appsanic project build, select Connectors → Supabase, and follow the setup guide beside the credential form. Connector OAuth is not currently available, so copy the project URL and keys from Supabase using the steps below.
Step 1: Sign up for Supabase and choose a current plan
Go to supabase.com and click Start your project. You can sign in with GitHub, or just an email + password.
Once you're in, click New project. You'll see a small form:
- Name: anything. Call it "My App" or "Habit Forge"; only you ever see this name.
- Database password: Supabase generates a strong one for you. Copy it and write it somewhere safe (a password manager, a note app). You probably only need it once, but Supabase cannot recover it for you if you lose it.
- Region: pick the one closest to your users. If your users are in North America, pick a US one. Europe? Frankfurt or Dublin. Asia-Pacific? Sydney or Singapore. This makes your app feel faster for people in that area.
- Plan: Free.
Click Create project. Supabase takes about a minute to spin everything up. While it's loading, you can read the next step.
Step 2: Find Supabase's settings page
When your project is ready, look at the left sidebar in the Supabase dashboard. At the bottom, click the ⚙️ gear icon ("Project Settings").
You're now on the settings page. Two sub-pages from here have what you need:
- "Data API": has your project's web address.
- "API Keys": has the two keys you'll paste in.
Step 3: Copy three things into Appsanic
Open Appsanic in a separate browser tab. Go to Dashboard → Connectors → Supabase. You'll see a form with three required fields.
Here's exactly where to find each one in Supabase:
| Appsanic field | Find it in Supabase at | What it looks like |
|---|---|---|
| Project address | Settings → Data API → "Project URL" | https://something.supabase.co |
| Public key | Settings → API Keys → "anon public" | Long string starting with sb_publishable_… or eyJ… |
| Admin key | Same page → API Keys → "service_role" | Long string. Hidden by default. Click Reveal first |
Copy each one carefully. The #1 reason connections fail is an accidental space when you copy. Click into the field, copy, click into Appsanic's matching field, paste. Don't paste anywhere else first.
A note on the difference between the two keys, since this confuses everyone:
- The public key is meant to be in your app. Phones get a copy of it. It's safe because Supabase only lets it do what your privacy rules allow. Think of it as the "shop's front door key". Everyone has it, but the front door only lets you into the public area.
- The admin key is the keys to everything. It bypasses every rule. It never leaves Appsanic's server. Phones never see it. We encrypt it before saving. Authorised connector code may use it only for an eligible bounded action, such as creating a declared storage bucket. For an existing bucket, Appsanic verifies the requested public setting, file-size limit, and allowed MIME types exactly; a mismatch stops without changing the bucket and requires a new explicit decision. SQL and sign-in policy changes stay review-first.
Step 4: Click Connect
Appsanic now runs a quick test to make sure your keys work. Three possible results:
- ✅ Connected: the public client configuration is available, while Account access still controls the small set of eligible build-time actions.
- ❌ "Invalid keys": almost always a copy-paste issue. Usually:
- An accidental space at the start or end of one of the keys (most common).
- The public key and admin key swapped (each goes in a specific field).
- The admin key copied while it was still hidden (you copied dots, not the real key).
Re-copy carefully, paste, click Connect again.
That's it. Supabase is available to this Appsanic project. The agent can use its public client configuration when the feature needs a cloud backend. Account access remains off until you opt in and exposes only the eligible build-time actions shown for the connection.
Looking at what's in your Supabase project
You don't have to. But if you want to peek:
From Appsanic, click Supabase dashboard at any time. Sign in to Supabase if necessary and confirm the connected project before changing data or settings.
Most useful Supabase tabs:
- Table Editor: every drawer of your filing cabinet. Click a table to see what's inside.
- Authentication → Users: every user who's signed up for your app. You can invite, ban, or delete users here if you ever need to.
- Storage: where uploaded files (photos, etc.) live.
- Logs: if something's not working, errors show up here.
Privacy: the most important thing happening invisibly
Every time the agent creates a table for user data, it also writes a rule that says:
"Only the user this row belongs to can see or edit it."
This rule lives in Supabase itself, not just in your app's code. Which means: even if there's a bug in your app, even if a hacker tried to ask for someone else's data, Supabase itself refuses.
It's a second locked door, deeper than the front door. The technical name is "Row Level Security." Any generated table plan should enable it and include an appropriate policy before you apply the SQL.
Verify this in the Supabase dashboard under Authentication → Policies. Every user-facing table should have at least one policy. Whether a change was applied by an eligible tool or by you from generated SQL, review the resulting policies before using real user data.
What it costs
Supabase plan limits, included storage, bandwidth, active-user allowances, backup retention, and idle-project behaviour change over time. Review the current Supabase pricing and your project's usage dashboard before launch. Configure spend controls and backups appropriate to the data's value.
Common scenarios
"I'm starting my second project. Do I need a new Supabase account?"
No. Connections are project-scoped. Each Appsanic project can connect to its own Supabase project, which is the recommended way to keep apps and environments isolated. You may point two Appsanic projects at the same Supabase project deliberately, but Appsanic will not do that automatically.
"I want to wipe everything and start over"
Two options in the Supabase dashboard, both under Settings → General:
- Reset database: wipes the data, keeps the project and its connection.
- Delete project: wipes everything irreversibly for a fresh slate (you confirm by typing the project name). Export anything you want to keep first, then click Disconnect in Appsanic → Dashboard → Connectors → Supabase before connecting a new project.
After a reset, ask the agent: "Reset complete. Rebuild the data structure for the app, recreate the tables, privacy rules, and any starter data."
"I need to change the region"
Once a Supabase project is created in a region, you can't move it. To change:
- Create a new Supabase project in the new region.
- For a brand-new app: just connect the new project to Appsanic.
- For an app with users already: export the data from the old project (Supabase dashboard → Database → Backups), create the new project, restore the backup, then update the connection in Appsanic.
The agent can walk you through this if you ask.
"Separate environments for development and production"
For more serious projects, you usually want separate Supabase projects for development, staging, and production. That way, you can experiment in development without affecting real users.
"Give me three environments: development, staging, production. Each has its own Supabase project."
The agent can generate separate client configurations and a migration checklist. You create and connect the Supabase projects, apply schema changes to each, and provision each deployed backend's runtime secrets separately. See Environment Variables.
"I accidentally shared my admin key publicly"
Bad day, but fixable.
- In the Supabase dashboard, go to Project Settings → API Keys.
- Click Reset service_role key. The old one stops working immediately.
- In the Appsanic project build, select Connectors → Supabase, enter the new admin key, and save.
- Look at the Logs tab in Supabase for any suspicious activity in the time the old key was exposed.
Things that go wrong
"Invalid keys" when I try to connect
Almost always a copy-paste issue. In order of how often we see it:
- An accidental space at the start or end of one of the keys. The fix: re-copy, paste carefully.
- Public and admin key swapped. Each goes in a specific field. Double-check you put the right one in each.
- Copied while the key was still hidden. Supabase masks the admin key by default. Make sure you clicked Reveal before copying.
- Project is unavailable or paused under its current plan. Check the Supabase dashboard for the project's current status and recovery action, then retry.
"My users can sign up but can't see any data"
This is the privacy rules doing their job, but too aggressively for the current case. Usually:
- You added data manually in the Supabase dashboard and forgot to set the user. The agent sets
user_idautomatically when creating data through code, but manual rows often forget. Edit those rows and fill in the correctuser_id. - The user just signed up and there's no data linked to them yet. That's the expected empty state.
- A bug in the privacy rules. Open Supabase → Authentication → Policies and check each table has a sensible rule.
If you're stuck, paste it into the chat: "Users can sign in but their data screen is empty even though there's data in the table." The agent looks at the policies and explains.
"A query is slow"
Free-tier Supabase usually has no performance issues for small apps. If a query gets slow, usually one of:
- The table has lots of rows and the query has no index.
- The query is asking for too much when it could ask for less.
- The app is making the same query repeatedly when it could cache the result.
Ask Sanic AI to review the slow query - it'll usually point right at the cause and propose an index or a tighter select.
"My app suddenly can't reach Supabase"
If your app was working and now every query fails, first check the Supabase dashboard for project health, plan limits, or a paused state, then inspect key rotation and provider status. Follow the recovery action shown for that project before reconnecting.
Under the hood (for engineers)
What's actually in your project after the agent wires Supabase up:
- Client: the
@supabase/supabase-jsSDK, initialised once and exposed from a smalllib/supabase.ts. Your project URL and anon key are inlined there as strings - an exported project has no.envfile, and the anon key is safe to bundle. Auth state lives in a Zustand store that the navigator (React Navigation v7) reads to fork between the signed-in and signed-out stacks. - Server-side work: anything that must bypass RLS (admin operations, webhooks, scheduled jobs) belongs in a trusted backend such as a Supabase Edge Function. The service-role key never reaches the app. Connector actions may perform eligible build-time setup; runtime functions and their secrets must be deployed and configured separately.
- Schema changes: written as complete
.sqlfiles withSETUP REQUIREDreview steps. You inspect and apply them in Supabase SQL Editor; the agent never claims they ran automatically. - Realtime: subscriptions via
supabase.channel(...).on('postgres_changes', ..., handler).subscribe(), cleaned up on unmount withremoveChannel. - Storage: the bounded account action can create or verify an explicitly declared bucket configuration. Bucket/object RLS policies are generated as review-first SQL and should namespace user files by
auth.uid()in the path (<bucket>/<user_id>/<filename>).
What Appsanic itself stores: the credentials you pasted in, encrypted at rest with context-bound envelope encryption, read only server-side when dispatching an eligible tool. The anon key is inlined into the app's code; the service-role key never leaves the server. Both key formats are accepted in the form - the new-style sb_publishable_* / sb_secret_* and the legacy eyJ* JWTs - and the validator normalises both.
Next
Read Database & Data for how the data side works in detail, or Authentication for the sign-in flow. Or just go build something. Every doc in the Building features section assumes Supabase is connected.
