Your backend isa folder of TypeScript

Define your database schema, server actions, and auth in a typebase/ folder inside your app. One command deploys a fully typed server your frontend calls like local functions.

typebase/actions/queries/todos.ts
server
import { action } from '../../_generated/server';
import { z } from 'zod';
 
export const getMany = action
.output(z.array(z.object({
id: z.number(),
value: z.string(),
})))
.handler(async ({ db }) => {
return db.query.todos.findMany();
});
src/app/page.tsx
client
import { client } from '@/lib/typebase/client';
 
export default async function Page() {
const todos = await client.queries.todos.getMany();
// ^? { id: number; value: string }[]
 
return todos.map((t) => (
<li key={t.id}>{t.value}</li>
));
}

Ships with first-class guides for

Next.js·SvelteKit
Nuxt·Expo

Idiomatic clients for each one: Server Components, SvelteKit load functions, Nuxt plugins, Expo SecureStore.

How it works

Zero to a deployed backend in two commands

Everything happens inside your codebase. The CLI handles codegen, schema pushes, and deployment.

  1. 01Scaffold

    One command creates a typebase/ folder in your existing app, with a database schema, example actions, and optional auth. No separate repo, no dashboard.

    $ npx typebase-io-cli init
  2. 02Write TypeScript

    Define tables in db/schema.ts, export actions from actions/, drop in auth.ts. Every export is typechecked end to end.

  3. 03Deploy

    Ships your folder as a server on Vercel, Cloudflare Workers, or Deno Deploy, with Postgres on Neon. Or generate the server code and host it anywhere. Typebase owns zero servers.

    $ npx typebase-io-cli deploy

Step 02, expanded

  • typebase/
  • actions/
  • mutations/
  • queries/
  • db/
typebase/actions/queries/todos.ts
you write this
// becomes client.queries.todos.getMany()
 
import { z } from 'zod';
 
import { action } from '../../_generated/server.ts';
 
export const getMany = action
.output(z.array(z.object({
id: z.number(),
value: z.string(),
completed: z.boolean(),
})))
.handler(async ({ db }) => {
return db.query.todos.findMany();
});

The problem
with RLS

RLS is implicit and lives in a SQL dialect your editor doesn’t typecheck. One UPDATE policy gives write access to every column, including the ones you add tomorrow. The overly permissive clause an agent slipped in at 2am sails through review, because no compiler is going to flag it.

vs.

With Typebase, authorization is explicit. Your action declares the columns it accepts and your auth check runs in code before any of them reach the database. Add a column, the compiler tells you who can write to it. The same code your agent writes is the code your compiler checks.

dashboard
AuthenticationPoliciespublic.todos4 policies
NameCmdUsing expressionStatus
Enable read for all
public
SELECTtrue
Active
Users can update todos
authenticated
UPDATEauth.role() = 'authenticated'
Active
Owners can delete
authenticated
DELETEuser_id = auth.uid()
Active
Owners can insert
authenticated
INSERTuser_id = auth.uid()
Active
Insecure policypolicy #2

auth.role() = 'authenticated' lets every signed-in user update every column of every row.

The DX of Convex. The openness of Supabase.

Typebase exists because we wanted both and couldn’t find it: backend functions that live in your code, backed by a database you actually own.

TypebaseSupabaseConvex
Backend logicTypeScript functionsSQL + RLS policiesTypeScript functions
DatabaseStandard PostgresPostgresProprietary
Type safetyEnd-to-end, always in syncGenerated, can driftEnd-to-end
Authbetter-auth, in one fileBuilt-in, dashboard configThird-party providers
InfrastructureYour cloud: Vercel, Cloudflare, DenoSupabase-hostedConvex-hosted
Vendor lock-inNone, eject anytimeMediumHigh

Realtime and storage aren’t there yet; they’re next on the roadmap. Read the full comparison

Industry-shaking testimonials*

* None of these people exist. We checked. Twice. Legal is chill.

I deleted 40,000 lines of REST plumbing last quarter. My tech lead cried. I think they were happy tears. I have stopped asking.
MV
Mariel Vonnegut
Principal Eng, AI unicorn you’ve heard of
Before Typebase I had three acronyms in my pipeline: REST, gRPC, and WHY. Now I have one: fn(). I have never been happier and my Oura ring agrees.
DD
Dave Dave
Senior Fullstack, maybe
I’ve told four separate therapists about Typebase. Two stopped taking me as a client. The other two are now shipping an app with it.
CR
Clementine Ryu
Engineer, between therapists
My co-founder asked where the auth lives. I said “a file called auth.ts.” He hasn’t spoken to me since. I assume he’s impressed.
TL
Tomás Lindberg
Indie hacker, possibly single
We replaced 14 microservices with one folder. The DevOps team threw me a party. The party was a meeting. The meeting was about layoffs.
A
Anonymous
For obvious reasons
10/10 would make my backend a folder again.
HP
Hannah Pollard
Senior Folder Engineer, self-appointed

Do you have a real, non-fabricated quote? We will happily replace one of these humans with you.

Give your agent a backend it can read.

It takes about ninety seconds. Most of that is npm install.

$ npm i typebase-io && npm i -D typebase-io-cli