You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Hono, H3, Elysia, and NestJS adapters in @supabase/server are deprecated and will be removed on December 1, 2026. Move to the framework bridges in the frameworks guide.
What is being deprecated
The four framework adapters that ship inside @supabase/server:
@supabase/server/adapters/hono
@supabase/server/adapters/h3
@supabase/server/adapters/elysia
@supabase/server/adapters/nestjs
They still work today. They will be removed from the package on December 1, 2026. No new adapters are accepted.
Nothing else changes. withSupabase(config, handler) is not deprecated. Neither is its entry form, withSupabase(config), nor any of the @supabase/server/middleware/* entries.
Why
Each adapter wrapped one call, withSupabase, for one framework. That meant a published entry point, a peer dependency range, and a release cycle per framework. @supabase/server has run on the @supabase/middleware engine since 1.5.1, and the engine replaced the model. A middleware is an entry you compose. The piece that is framework-specific is a short bridge, and that file belongs in your project, not in a package that has to track your framework's major versions.
Timeline
The @supabase/server README has carried the deprecation warning since 1.9.0. From 1.9.1, every adapter export carries an @deprecated tag and each adapter doc opens with the same warning. The adapters are removed on December 1, 2026.
What to migrate to
A bridge: one file you copy into your project. It runs a @supabase/middleware entry array inside your framework's own middleware slot. Your route handlers then read supabase, jwtClaims, and any other key the entries contribute from where your framework keeps per-request state. Bridges exist for Hono, H3, Elysia, NestJS, and TanStack Start, and they typecheck in CI.
The bridges need @supabase/server 1.6.0 or later and Node 22 or later. The bridge file imports @supabase/middleware, so add it to your project as a direct dependency.
The frameworks guide has the bridge for each framework, the full migration steps, and a prompt you can hand to a coding agent to do the migration for you.
Migration steps
Inventory every adapter registration. Grep for @supabase/server/adapters and note the auth value each withSupabase(...) call uses. A bare withSupabase() counts as auth: 'user'.
Decide the replacement for each auth value. auth: 'user' becomes withRequiredClaims(). auth: 'none' needs no gate. auth: 'publishable' and auth: 'secret' have no bridge entry; those endpoints stay on withSupabase.
Do not use withClaims() in place of auth: 'user'. The adapter rejected anonymous requests. withClaims() lets them through with jwtClaims: null, which turns a 401 into a 200 with no error.
Add @supabase/middleware as a direct dependency, then copy the bridge for your framework from examples/frameworks as is, comments included.
Swap each registration for the bridge called on an entry array, for example toHono([withRequiredClaims(), withSupabaseClient()]).
Rewrite the call sites. The adapters exposed one nested supabaseContext object. The entries contribute flat keys: c.var.supabase, c.var.jwtClaims. No entry contributes userClaims. userClaims.id becomes jwtClaims.sub.
Verify. Run the typecheck. Then confirm that every endpoint that rejected anonymous requests before still returns 401 without a token.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
The Hono, H3, Elysia, and NestJS adapters in @supabase/server are deprecated and will be removed on December 1, 2026. Move to the framework bridges in the frameworks guide.
What is being deprecated
The four framework adapters that ship inside
@supabase/server:@supabase/server/adapters/hono@supabase/server/adapters/h3@supabase/server/adapters/elysia@supabase/server/adapters/nestjsThey still work today. They will be removed from the package on December 1, 2026. No new adapters are accepted.
Nothing else changes.
withSupabase(config, handler)is not deprecated. Neither is its entry form,withSupabase(config), nor any of the@supabase/server/middleware/*entries.Why
Each adapter wrapped one call,
withSupabase, for one framework. That meant a published entry point, a peer dependency range, and a release cycle per framework.@supabase/serverhas run on the@supabase/middlewareengine since 1.5.1, and the engine replaced the model. A middleware is an entry you compose. The piece that is framework-specific is a short bridge, and that file belongs in your project, not in a package that has to track your framework's major versions.Timeline
The
@supabase/serverREADME has carried the deprecation warning since 1.9.0. From 1.9.1, every adapter export carries an@deprecatedtag and each adapter doc opens with the same warning. The adapters are removed on December 1, 2026.What to migrate to
A bridge: one file you copy into your project. It runs a
@supabase/middlewareentry array inside your framework's own middleware slot. Your route handlers then readsupabase,jwtClaims, and any other key the entries contribute from where your framework keeps per-request state. Bridges exist for Hono, H3, Elysia, NestJS, and TanStack Start, and they typecheck in CI.The bridges need
@supabase/server1.6.0 or later and Node 22 or later. The bridge file imports@supabase/middleware, so add it to your project as a direct dependency.The frameworks guide has the bridge for each framework, the full migration steps, and a prompt you can hand to a coding agent to do the migration for you.
Migration steps
@supabase/server/adaptersand note theauthvalue eachwithSupabase(...)call uses. A barewithSupabase()counts asauth: 'user'.authvalue.auth: 'user'becomeswithRequiredClaims().auth: 'none'needs no gate.auth: 'publishable'andauth: 'secret'have no bridge entry; those endpoints stay onwithSupabase.withClaims()in place ofauth: 'user'. The adapter rejected anonymous requests.withClaims()lets them through withjwtClaims: null, which turns a 401 into a 200 with no error.@supabase/middlewareas a direct dependency, then copy the bridge for your framework fromexamples/frameworksas is, comments included.toHono([withRequiredClaims(), withSupabaseClient()]).supabaseContextobject. The entries contribute flat keys:c.var.supabase,c.var.jwtClaims. No entry contributesuserClaims.userClaims.idbecomesjwtClaims.sub.Affected products: supabase-server
Action required before: 2026-12-01
Authored by @mandarini
All reactions