- ›
/backend— the data layer for agent-built apps: managed Postgres, file storage, end-user auth, and edge functions, all on one fullstack app - ›
One call provisions everything— create a `type: "fullstack"` app and the database, storage, auth, and functions come online together - ›
Database— raw SQL, PostgREST CRUD, and tracked migrations against managed Postgres, with the project ref auto-resolved - ›
Storage— create buckets and read/write objects on the app's project without touching a storage dashboard - ›
Auth— configure end-user authentication and manage users through an admin API, service-role key held server-side - ›
Edge functions— deploy and invoke serverless functions; the agent never sees a raw provider secret
Today we're launching the /backend stack — the data layer for the apps your agent ships. Managed Postgres, file storage, end-user authentication, and edge functions, all provisioned together and driven through the same Naïve API key. No Supabase dashboard. No service-role secret ever leaving the runtime. Your agent stands up a real backend the same way it does everything else: one call.
The problem: a deployed app is only half a product
/apps lets an agent deploy a real web application from a prompt. But an app without a backend is a brochure. The moment you want to store a user, save a record, upload a file, or run a bit of server logic, an agent hits the same wall a human does:
- Provisioning a database means a dashboard. Click through a project creation flow, copy a connection string, paste it into env vars. Agents don't click dashboards.
- The service-role key is radioactive. It's the key that bypasses every security rule. Handing it to an autonomous agent — or worse, embedding it in generated app code — is exactly the kind of mistake the runtime should make impossible.
- Four services, four integrations. Database, storage, auth, and functions are usually four SDKs, four sets of credentials, and four mental models. For an agent, that's four ways to get stuck.
The result is that "build me an app with login and a database" quietly becomes a human task again. Until now.
How the backend stack works
Everything hangs off a single fullstack app. When you create an app with type: "fullstack", Naïve provisions a managed Postgres + Supabase project alongside the Vercel deployment. That one project is what the four backend primitives operate on:
- Database — raw SQL, PostgREST CRUD, and tracked migrations against managed Postgres.
- Storage — buckets and objects for files and assets.
- Auth — end-user authentication config plus admin user management.
- Edge Functions — deploy and invoke serverless functions.
Every call routes through an app-scoped proxy. The project's service-role key lives server-side; the agent authenticates with its normal nv_sk_* key, and Naïve attaches the right project credential behind the scenes. The SDK auto-resolves your single fullstack app, so methods never take a project ref — pass { appId } only if a user owns more than one.
# Stand up the app that owns the backend
naive apps create --name "My SaaS" --type fullstackDatabase: SQL, CRUD, and migrations
The database client gives you three ways to work, from raw SQL to typed CRUD:
// Apply a schema change (DDL)
await naive.database.migrate(
"create table posts (id uuid primary key default gen_random_uuid(), title text, created_at timestamptz default now())"
);
// PostgREST-style CRUD
await naive.database.from("posts").insert({ title: "Hello world" });
const recent = await naive.database.from("posts").select("*", "order=created_at.desc");
// Raw SQL when you need it
const rows = await naive.database.query("select count(*) from posts");
// Introspect the schema
const { tables } = await naive.database.tables();query and the from(...) CRUD helpers use the service-role key and bypass row-level security — they're built for trusted agent and server-side use. For your end-users' app traffic, set up RLS policies and use the anon/auth keys in your app code as usual.
Storage: buckets and objects
File storage is one call away — no separate bucket provisioning step, no storage dashboard:
await naive.storage.createBucket("uploads", { public: true });
await naive.storage.upload("uploads", "notes.txt", "hello world");
const objects = await naive.storage.list("uploads", { prefix: "" });
const file = await naive.storage.download("uploads", "notes.txt");Text and JSON objects upload directly; for binary uploads, request a signed URL and stream the file to it. Objects live on the same project as your database, so a record and the file it points at never drift apart.
Auth: end-user authentication and admin users
The auth primitive covers both halves of authentication — configuring how end-users sign in, and managing those users administratively:
// Configure auth for the app
await naive.auth.updateConfig({ site_url: "https://myapp.com" });
// Admin user management (GoTrue)
await naive.auth.users.create({ email: "user@example.com", password: "a-strong-password" });
const { users } = await naive.auth.users.list();Admin user management runs through GoTrue with the service-role key held server-side, so an agent can provision and manage your application's users without ever holding the credential that lets it do so.
Edge functions: serverless logic on demand
When an app needs a bit of server-side logic — a webhook handler, a scheduled cleanup, a signed-URL minter — deploy it as an edge function and invoke it like any other call:
// Invoke a deployed function
const result = await naive.functions.invoke("send-welcome", { email: "user@example.com" });
// List what's deployed
const fns = await naive.functions.list();Functions run on the app's project, so they share its database, storage, and auth without extra wiring.
What you can build with the backend stack
Ship a full SaaS from a single prompt — Pair /backend with /apps and /orchestration. An engineer Employee scaffolds the schema with migrate, wires up auth, deploys the frontend, and the product is live with real persistence — not a mock.
Give every customer their own isolated backend — Provision a fullstack app per tenant. Each customer gets a dedicated database, storage, and auth project, so data isolation is physical, not a WHERE tenant_id = clause you hope nobody forgets.
Let an agent own its application data — A support or analytics Employee can read and write to the same Postgres your app uses, run ad-hoc SQL to answer questions, and store results — all auditable, all through the runtime.
Store generated assets next to their records — Generate a logo with /image, drop it in a storage bucket, and reference it from a row — one project, one key, no cross-service plumbing.
Add server logic without a deploy pipeline — Push an edge function for the one operation that shouldn't run on the client, and invoke it from the app or from an agent loop.
Get started
Drop this starter prompt into any coding agent to wire up Naïve:
Read https://usenaive.ai/skill.md and use it to set up Naïve in my project.
- Database: usenaive.ai/docs/getting-started/database
- Storage: usenaive.ai/docs/getting-started/storage
- Auth: usenaive.ai/docs/getting-started/auth
- Edge functions: usenaive.ai/docs/getting-started/functions
- Deploy the app that owns it: usenaive.ai/docs/getting-started/apps
- Quickstart: usenaive.ai/docs/getting-started/quickstart
- Join the community on Discord