Finding signal on Twitter is more difficult than it used to be. We curate the best tweets on topics like AI, startups, and product development every weekday so you can focus on what matters.
Today we're releasing @supabase/server in public beta.
This is a new package that handles auth verification, client setup, request context, and common server-side boilerplate for you. It works across Edge Functions, Cloudflare Workers, Hono, and Bun.
We anonymously analyzed 25,000 deployed Edge Functions and saw the same pattern everywhere: developers were rebuilding the same setup code over and over just to get to their actual business logic.
Most functions needed to:
Create a Supabase client with SUPABASE_ANON_KEY
Create another admin client with `SUPABASE_SERVICE_ROLE_KEY` that can bypass Row Level Security
Verify the JWT
Parse claims
Handle CORS
Wire up the auth context
Copy/paste the same `_shared/*.ts` files between functions
With @supabase/server you just declare who can call your endpoint and get a fully initialized context back:
User-scoped Supabase client
Admin client with service role access
Verified user identity
JWT claims
Built-in request/auth helpers
Note that export default { fetch } is equivalent to Deno.serve(...). Both define a request handler. We use export default throughout this post because it works across Edge Functions, Workers, and Bun. If you prefer Deno.serve, you can keep using it — it's still supported on Edge Functions.
How it works
At the core of `@supabase/server` is the `SupabaseContext`: a request context that includes everything most Edge Functions need, already configured for you.
Auth metadata @supabase/server gives you multiple ways to get a SupabaseContext. The most common is withSupabase, a wrapper that handles auth, client creation, and CORS before your handler runs:
If you need more control over error handling and responses, you can also call createSupabaseContext directly:
Both approaches give you the same SupabaseContext. No shared utility files. No environment variable management. No manual JWT verification.
What's in the context
Every withSupabase handler receives a ctx object with two pre-configured clients:
ctx.supabase — a user-scoped client that automatically respects RLS policies ctx.supabaseAdmin — an admin client using the service role for privileged operations No manual client setup, JWT verification, or environment variable wiring required.
The full context looks like this:
Declarative access control
With @supabase/server, authentication happens before your handler runs.
You declare who is allowed to call the endpoint, and the package handles verification automatically.
For example, this endpoint allows unauthenticated requests:
This endpoint requires a valid user JWT:
If the request does not include a valid user token, the request is rejected before your handler executes.
Here's all of the auth modes included in the package:
Your function's security model is visible in one line.
Adopting new auth keys without the boilerplate
Last year we improved project security with asymmetric JWT Signing Keys and new API keys. Better security for every project, but migrating existing functions was hard.
You had to install jose, configure a JWKS endpoint, build your own auth middleware, expose new secrets, and update every function individually.
We fixed it. @supabase/server handles new key validation and JWT verification internally. You adopt the package, and the new security model comes with it. No jose. No JWKS configuration. No manual secret setup.
Now you get support for the new auth keys without manual JWT verification. Delete your shared utility files and focus on business logic.
Same code, every runtime withSupabase returns a standard (Request) => Promise<Response> handler. It works with any runtime that supports the Web API pattern.
Edge Functions and Cloudflare Workers:
Hono (with the included adapter):
Composable primitives
Most developers don't need anything beyond `withSupabase` or `createSupabaseContext`. But you can use the underlying primitives directly.
These are useful when you need more control: multiple routes with different auth, custom response headers, or domain-specific wrappers like MCP servers.
Here's an Edge Function with per-route auth:
These are the same primitives that power withSupabase. Teams building MCP servers, custom middleware, or framework adapters can compose them into their own patterns.
One pattern for humans and AI agents
We designed @supabase/server with agentic development in mind. Every function follows the same structure: declare access, receive context, write logic.
During internal testing, Claude Code migrated an entire project's Edge Functions to @supabase/server in a single prompt. That included adopting new API keys, removing shared utility files, and switching every function to withSupabase. All functions worked on the first run.
When every function looks the same, agents produce correct code from a single example.
The skill gives Claude Code and Cursor full context about the API surface, patterns, and migration paths. From there, you can prompt your way through most tasks.
Migrate existing Edge Functions to the new API keys:
Analyze all Edge Functions, and plan a full migration to use
the new API keys with @supabase/server
Scaffold a new REST API with Hono:
Create a Hono API with @supabase/server that has CRUD
endpoints for a todos table, using per-route auth
Add a protected Edge Function with admin operations:
Create an Edge Function that accepts user or secret key auth,
reads from a user's profile with RLS, and writes audit logs
with the admin client