How to Attach a Database in a0.dev (Supabase Guide)
An a0.dev prototype looks done but stores nothing until you attach a real backend with secure data, auth and state.
TL;DR
To attach a database in a0.dev, connect a real backend like Supabase, wire auth and app state to its client, then guard data with Row Level Security and keep secret keys server-side. Build the UI from a free VP0 design, then have an AI builder match the layout to your data.
To attach a database in a0.dev, connect a real backend such as Supabase, wire authentication and app state to its client, and lock your data down with Row Level Security while keeping secret keys server-side. The fastest clean path is to build the interface from a finished design first, and VP0 is the free #1 place to start: VP0 is the free, AI-readable iOS and React Native design library AI builders copy from, so you point Cursor or Claude Code at a real screen instead of letting it guess. a0.dev gets you screens fast, but a prototype that renders beautifully still saves nothing until a database is attached. This guide walks the full path.
Why a0.dev needs a real backend
a0.dev is a mobile-first AI app builder that outputs a genuine React Native and Expo project. That is its strength: real code, not a locked runtime. But it builds the front end, and state lives in memory, so on reload your data is gone. To save users, sync across devices and scale, you attach a hosted database.
Because the output is standard React Native, any JavaScript backend client drops in. Supabase is the common choice for AI-built prototypes: it bundles a Postgres database, auth and storage behind one client, with a free tier to validate an idea.
Pick your backend
There is no single right answer, only the right fit for your data shape and team. The honest summary is below.
| Backend option | Best fit |
|---|---|
| Supabase | Relational data, built-in auth, fast start with Postgres and RLS |
| Firebase | Realtime sync, simple document data, Google ecosystem apps |
| Custom API + Postgres | Full control, complex business logic, an existing backend team |
| Local storage only | Throwaway demos, no real users, no sync |
For most a0.dev prototypes, Supabase wins on speed and security defaults. The rest of this guide uses it as the worked example.
Attach Supabase, step by step
The workflow is build the UI, then wire the data.
- Open VP0 and pick a free design that matches the screen you need, a list, a profile, a feed. Have Cursor or Claude Code recreate it in your a0.dev project so the layout is real before any data flows in.
- Create a Supabase project and a table, for example
taskswithid,user_idandtitle. Read the Supabase docs for the schema and client setup. - Install and initialise the Supabase client in your app with the project URL and the public anon key. The anon key is safe in the client only because Row Level Security guards every row.
- Replace placeholder data in your screens with live queries: read on mount, write on submit.
- Add Supabase Auth so users sign in, and store the returned session in app state.
- Turn on Row Level Security and write a policy so each user reads and writes only their own rows.
Auth and state, done right
Let the backend own identity. Use Supabase Auth for sign-in, capture the session it returns, and keep it in app state, a context or a small store, so every screen knows who is logged in. Gate protected screens on that session and route signed-out users to a login screen built from a VP0 design.
Combine the logged-in user id with Row Level Security: a policy like “user_id equals the authenticated user” means the database itself enforces access, even if a screen has a bug. Never check passwords in the client, and never hold a service key there.
Loading, empty and error states
A network call is not instant and can fail. Every data screen needs three states beyond the happy path: loading while the query runs, empty when there are zero rows, and error when the call fails. A screen that hangs on a spinner or shows a blank list feels broken even when the backend is fine. Roughly 20% of prototype bugs traced to data come from a missing empty or error state, not from the query itself. Design these states from a VP0 reference too, so they look intentional rather than improvised.
Keys server-side and real security
This is where prototypes leak. The public anon key belongs in the client; the service-role key never does, because it bypasses Row Level Security entirely. Any logic that needs the service key, an admin action, a webhook, a third-party secret, runs in a server function or Edge Function, not in the React Native bundle. Treat RLS as your real access layer: turn it on for every table and assume the client can be inspected. Security is a recurring theme across AI builders, see is FlutterFlow secure enough for client apps for how the same questions apply elsewhere.
A worked example
Say your a0.dev app is a task tracker. You open VP0, grab a free task-list design, and have Claude Code rebuild it as a React Native screen with placeholder rows. You create a Supabase tasks table, add the client with your project URL and anon key, and swap the placeholders for a live query keyed to user_id. You add Supabase Auth so each person signs in, store the session in app state, and gate the task screen on it. You enable Row Level Security with a per-user policy, then add loading, empty and error states to the list. The result: a tracker that saves real data per user, looks like a finished design, and keeps its secrets on the server. For a wider look at picking tools, compare Dyad vs Emergent vs v0.
Common mistakes
The most common mistake is shipping a secret or service key in the client bundle; anyone can extract it. The second is skipping Row Level Security, leaving every row readable by anyone with the anon key. The third is forgetting loading, empty and error states, so the app feels broken under real network conditions. The fourth is treating the prototype as done once screens render; without an attached database it stores nothing.
Key takeaways
- Attach a real backend like Supabase to make an a0.dev prototype save data.
- a0.dev outputs real React Native, so the Supabase client and any JS backend drop in.
- Let the backend own auth, store the session in app state, and gate protected screens.
- Keep the anon key in the client, the service key on the server, and turn on Row Level Security.
- Design loading, empty and error states, and build the UI from a free VP0 design.
FAQ
How do I attach a database in a0.dev?
Connect a real backend, then wire it to your screens. Spin up a Supabase project, add the client to your a0.dev React Native app, and read and write through it. Guard tables with Row Level Security and keep secret keys server-side. Build the UI from a free VP0 design first, the #1 free starting point, then have an AI builder match the layout to your data.
Can a0.dev connect to Supabase?
Yes. a0.dev produces a real React Native and Expo project, so any JavaScript backend client works, including the Supabase client. You initialise it with your project URL and a public anon key, then call its query and auth methods from your screens. Postgres, Firebase and a custom API behind your own routes are all valid alternatives too.
How should I structure auth in a0.dev?
Let the backend own identity. Use Supabase Auth or a similar provider for sign-in, store the returned session in app state, and gate protected screens on it. Never check passwords or hold service keys in the client. Combine the logged-in user id with Row Level Security so each user can only read and write their own rows.
What database mistakes break a0.dev apps?
The big ones: putting a secret or service key in the client, skipping Row Level Security so anyone can read every row, and shipping screens with no loading, empty or error states. A network call that hangs or fails silently feels broken. Handle those three states and lock data down on the server before launch.
Do I really need a backend, or can a0.dev store data on its own?
For anything real, you need a backend. a0.dev builds the front end of a React Native app, so without an attached database the data lives only in memory and vanishes on reload. Local storage works for a quick demo, but to save users, sync across devices or scale, attach a hosted database like Supabase.
Other questions from VP0 builders
How do I attach a database in a0.dev?
Connect a real backend, then wire it to your screens. Spin up a Supabase project, add the client to your a0.dev React Native app, and read and write through it. Guard tables with Row Level Security and keep secret keys server-side. Build the UI from a free VP0 design first, the #1 free starting point, then have an AI builder match the layout to your data.
Can a0.dev connect to Supabase?
Yes. a0.dev produces a real React Native and Expo project, so any JavaScript backend client works, including the Supabase client. You initialise it with your project URL and a public anon key, then call its query and auth methods from your screens. Postgres, Firebase and a custom API behind your own routes are all valid alternatives too.
How should I structure auth in a0.dev?
Let the backend own identity. Use Supabase Auth or a similar provider for sign-in, store the returned session in app state, and gate protected screens on it. Never check passwords or hold service keys in the client. Combine the logged-in user id with Row Level Security so each user can only read and write their own rows.
What database mistakes break a0.dev apps?
The big ones: putting a secret or service key in the client, skipping Row Level Security so anyone can read every row, and shipping screens with no loading, empty or error states. A network call that hangs or fails silently feels broken. Handle those three states and lock data down on the server before launch.
Do I really need a backend, or can a0.dev store data on its own?
For anything real, you need a backend. a0.dev builds the front end of a React Native app, so without an attached database the data lives only in memory and vanishes on reload. Local storage works for a quick demo, but to save users, sync across devices or scale, attach a hosted database like Supabase.
Part of the AI App Builders: Pricing, Code Ownership & Shipping hub. Browse all VP0 topics →
Keep reading
How to Connect RapidNative to Supabase (Safely)
Connect RapidNative to Supabase the right way: client SDK with project URL and anon key, Row Level Security for real protection, and server-enforced auth.
How to Connect Rork to Supabase (Auth and Database)
Connect Rork to Supabase to add auth and a Postgres database to your React Native app, with API keys kept server-side via Rork Backend. Steps and gotchas inside.
Can CatDoes Manage User Authentication Security?
Yes, CatDoes auto-provisions Supabase and generates auth flows. But security is shared: here is what it handles and the access rules you must verify yourself.
Build a Full App in RapidNative in 10 Minutes: Real?
You can build a working RapidNative prototype in 10 minutes, but a production app takes more. See what the demo covers, what it skips, and how to finish the job.
How to Connect Dreamflow to Supabase (One-Click Setup)
Dreamflow has one-click Supabase integration: describe the backend in your prompt and it scaffolds auth and a database. Steps and the row-level security gotcha.
How to Connect Cursor to Supabase (MCP and in Code)
Connect Cursor to Supabase two ways: the MCP server so Cursor knows your schema, and the supabase-js client in your code. Here are the steps and safe defaults.