OTFotf
All posts

Supabase Server is here — our next kit ships with it built in

D
DaveAuthor
5 min read
Supabase Server is here — our next kit ships with it built in

The standard way to write a Supabase Edge Function has looked like this for a while:

import { createClient } from '@supabase/supabase-js'

Deno.serve(async (req) => {
  const token = req.headers.get('Authorization')?.replace('Bearer ', '')
  const supabase = createClient(
    Deno.env.get('SUPABASE_URL')!,
    Deno.env.get('SUPABASE_ANON_KEY')!,
    { global: { headers: { Authorization: req.headers.get('Authorization')! } } }
  )
  const { data: { user } } = await supabase.auth.getUser(token)
  if (!user) return new Response('Unauthorized', { status: 401 })
  // actual logic starts here
})

Supabase analyzed 25,000 deployed Edge Functions and found this block — or a recognizable variation of it — in nearly all of them. Yesterday they shipped @supabase/server to fix it.

What @supabase/server does

Instead of wiring auth, RLS-scoped clients, and admin clients by hand on every route, you get a pre-initialized context:

import { EdgeFunctionHandler } from '@supabase/server'

export default EdgeFunctionHandler({ accessLevel: 'user' }, async ({ user, supabase, adminClient }) => {
  // user is verified
  // supabase is RLS-scoped to that user
  // adminClient bypasses RLS for admin operations
  const { data } = await supabase.from('todos').select('*')
  return Response.json(data)
})

Authentication mode is declared once — accessLevel: 'user' | 'unauthenticated' | 'secret-key' | 'publishable-key'. JWT verification, asymmetric key rotation, and client creation all happen behind the scenes.

It also works outside of Supabase's own runtime: Vercel Functions, Cloudflare Workers, Hono, H3, Bun, Deno. The return type is a standard (Request) => Promise<Response>, so you drop it into any router.

Why this matters for kit builders

Every full-stack kit we've shipped at OTF — SaaS Dashboard, Fitness — follows the same server pattern: a Hono router, per-route auth middleware, Drizzle over Postgres. It works. But it means every kit carries its own auth scaffolding, which means every kit owner debugging auth is debugging something slightly different.

@supabase/server makes auth a platform concern, not a kit concern. The route-level access declaration is consistent across every kit. The client wiring is gone. The only thing each route owns is the thing it should own: the business logic.

That's the model we're using for the next OTF kit.

What's coming: OTF × Supabase Kit

The next kit in the OTF lineup will be the first one built on Supabase end-to-end:

  • Auth — Supabase Auth via @supabase/server, social providers + email/password + magic link, zero boilerplate at the route level
  • Database — Supabase Postgres with Row Level Security written at the kit level, not scattered across queries
  • API — Hono routes using EdgeFunctionHandler, consistent access levels, no custom middleware
  • Realtime — Supabase Realtime subscriptions wired into the component layer so the UI reacts without polling
  • Storage — Supabase Storage for file uploads, connected to the OTF upload components

Same stack you know from the existing kits — React + TypeScript + Tailwind + OTF components — but Supabase replaces the self-managed Postgres + Better Auth setup. Less infrastructure to own, same amount of control.

It ships with the same AI config files every OTF kit includes: CLAUDE.md, .cursorrules, AGENTS.md, and tested prompts written specifically for the Supabase primitives — so you're not back-filling context after you buy.

When

We're targeting a release in the next few weeks. If you want early access or want to shape what's in the kit, join the Discord or watch the changelog.

Read the full @supabase/server announcement on the Supabase blog.

supabasebackendkitsannouncement

On this page

Supabase Server is here — our next kit ships with it built in | OTF Blog | OTF