A batteries-included backend that deploys wherever you already run code.
Outer is an alternative to Supabase, PocketBase, and Firebase, built on Kysely, oRPC, and Better Auth. A single builder chain gives you typed schema migrations, auto-CRUD resources, auth, and realtime — with no vendor lock-in and no external services to provision.
Everything a small backend needs, none of the infra.
One fetch-compatible handler. Chain .schema(), .auth(), .middleware(), and .procedure() in order, then .build() and serve it from Node, Hono, H3, or Next.js API routes.
Define tables and relations with schema(), and every .schema() call becomes a migration step that advances your DB type. Call .resource("post", ...) and get list, get, create, update, and delete procedures for free, with clean 409/400/404 error mapping instead of raw 500s.
.schema(v1_0)
.resource("post", {
permissions: {
list: "public",
create: "authenticated",
update: "owner",
delete: "owner",
},
ownerColumn: "userId",
})
// -> post.list, post.get, post.create,
// post.update, post.delete.auth() mounts Better Auth at /api/auth/** and accepts every Better Auth option directly. Resource permissions — public, authenticated, owner, admin — are declared per-procedure, with owner checks and user-id injection handled automatically.
.auth({ secret: process.env.AUTH_SECRET! })
.middleware(async ({ context, next }) => {
const session = await context.auth.api
.getSession({ headers: context.headers });
return next({ context: { user: session?.user } });
})Stream updates over SSE with oRPC's event iterators and EventPublisher — an async generator in a .procedure() handler is all it takes to fan events out to subscribers, with resumable delivery via withEventMeta.
.procedure("post.live", (base) =>
base
.output(eventIterator(z.object({ id: z.number() })))
.handler(async function* ({ signal }) {
for await (const row of postEvents.subscribe(
"created",
{ signal },
)) {
yield withEventMeta(row, { id: String(row.id) });
}
}),
)pglite() ships a zero-infra embedded Postgres that writes to local disk — perfect for a VPS or Coolify box. Need serverless or edge? Swap in any Kysely Dialect (Neon, D1, Durable Objects) with the same builder chain — templates/cloudflare and templates/vercel-neon ship with a ready deploy script.
$ npm run deploy
# templates/cloudflare -> wrangler deploy
# templates/vercel-neon -> vercel deploy --prodYour backend, your data, your infrastructure.
No hosted control plane, no proprietary APIs, no data leaving your own servers. Install the package, write your schema, and ship.