---
slug: supabase-server-adapters-deprecated
published: 2026-10-05
change_type: deprecation
affected_products:
  - supabase-server
page: https://supabase.com/changelog/supabase-server-adapters-deprecated
---

# Framework adapters in @supabase/server are deprecated

## 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](https://supabase.com/docs/reference/server/frameworks) 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

1. 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'`.
2. 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`.
3. 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.
4. Add `@supabase/middleware` as a direct dependency, then copy the bridge for your framework from [`examples/frameworks`](https://github.com/supabase/server/tree/main/examples/frameworks) as is, comments included.
5. Swap each registration for the bridge called on an entry array, for example `toHono([withRequiredClaims(), withSupabaseClient()])`.
6. 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`.
7. Verify. Run the typecheck. Then confirm that every endpoint that rejected anonymous requests before still returns 401 without a token.
