docs(auth): add server-side package disambiguation guide (#47966)

Adds a docs guide, "Choosing a server-side package", that explains when
to use `supabase-js`, `@supabase/ssr`, or `@supabase/server` when
working with Supabase from JavaScript on the server. It includes a
decision table and a short code example for each, with one rule up
front: cookie-based sessions in SSR frameworks use `@supabase/ssr`,
per-request header auth in Edge Functions and other backend runtimes
uses `@supabase/server`, and `supabase-js` is the base client both wrap.

The guide is surfaced from the Auth overview page and the sidebar, and
is cross-linked from the `supabase-js` and `@supabase/server` reference
introductions so it is reachable from where developers start. It also
states that the packages coexist and are not replacements for each
other, and keeps combining `@supabase/server` with `@supabase/ssr` as an
advanced section.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added a guide explaining how to choose between Supabase server-side
JavaScript packages.
- Added the guide to Auth navigation and the getting-started content
listings.
- Added links to the new guidance throughout relevant JavaScript and
server documentation.
- **Documentation**
- Clarified when to use cookie-based sessions versus header-based
authentication.
- Added package comparisons, usage examples, advanced guidance, and
related next steps.
- Updated spelling support for framework names used in the
documentation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Katerina Skroumpelouandgithub-actions[bot] authored and GitHub committed 2026-07-16 15:29:00 +03:00
1 parent a72a58eeae
commit dac5756295
8 files changed
+118

No files matched your search

@@ -740,6 +740,10 @@ export const auth: NavMenuConstant = {
name: 'Flows (How-tos)',
enabled: authFlowsEnabled,
items: [
{
name: 'Which package to use',
url: '/guides/auth/choosing-a-server-package',
},
{
name: 'Server-Side Rendering',
url: '/guides/auth/server-side',
@@ -0,0 +1,95 @@
---
title: 'Which package to use'
subtitle: 'When to use supabase-js, @supabase/ssr, or @supabase/server on the server.'
---
When you use Supabase from JavaScript on the server, there are three packages to choose from. They are not alternatives to each other — `@supabase/ssr` and `@supabase/server` both build on top of `supabase-js` and solve different problems. This guide helps you pick the right one.
<Admonition type="note">
These are JavaScript packages, not separate language SDKs. If you're looking for the client library for another language (Python, Swift, Kotlin, etc.), see the [client library references](/docs/reference).
</Admonition>
## Which package to use
The quickest way to decide is by **how the user's identity reaches your code**:
- The session lives in **cookies** (an SSR framework like Next.js or SvelteKit) → use **`@supabase/ssr`**.
- Auth arrives **per request in headers** (`Authorization: Bearer <jwt>`) → use **`@supabase/server`**.
- You want the base client, or you're handling auth yourself → use **`@supabase/supabase-js`** directly.
| Package | Use it when | Runs in | Auth model |
| ----------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------------------------------------- |
| `@supabase/supabase-js` | You want the base client, or you manage auth yourself | Browser and server | You wire up auth |
| `@supabase/ssr` | User sessions are stored in **cookies** | SSR frameworks (Next.js, SvelteKit, TanStack Start) | Cookie-based sessions, with refresh-token rotation |
| `@supabase/server` | Auth arrives **per request in headers** | Edge Functions, Workers, Vercel, Bun, and framework APIs (Hono, H3, Elysia, NestJS) | Stateless Bearer JWT + `apikey` |
## `@supabase/supabase-js`
The isomorphic base client. `@supabase/ssr` and `@supabase/server` both wrap it — reach for `supabase-js` directly when you don't need either wrapper's auth handling.
```ts
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(process.env.SUPABASE_URL!, process.env.SUPABASE_PUBLISHABLE_KEY!)
```
## `@supabase/ssr`
For SSR frameworks that store the user's session in cookies. It reads and writes session cookies and handles refresh-token rotation, so the same user and session are available on both the client and the server.
```ts
import { createServerClient } from '@supabase/ssr'
const supabase = createServerClient(
process.env.SUPABASE_URL!,
process.env.SUPABASE_PUBLISHABLE_KEY!,
{
cookies: {
getAll() {
// return the request's cookies
},
setAll(cookiesToSet) {
// write cookies back on the response
},
},
}
)
```
See the [server-side rendering guide](/guides/auth/server-side) for framework-specific setup.
## `@supabase/server`
For stateless, header-based auth in backend runtimes — Edge Functions, Workers, and framework APIs. You declare who may call an endpoint and receive a ready-to-use context (a caller-scoped client that respects RLS, plus an admin client). It verifies JWTs and resolves the new API keys (`SUPABASE_PUBLISHABLE_KEYS` / `SUPABASE_SECRET_KEYS`) for you.
```ts
import { withSupabase } from '@supabase/server'
export default {
fetch: withSupabase({ auth: 'user' }, async (req, ctx) => {
// ctx.supabase is scoped to the caller and respects RLS
const { data } = await ctx.supabase.from('todos').select()
return Response.json(data)
}),
}
```
See the [`@supabase/server` reference](/docs/reference/server) for the full API.
<Admonition type="note">
`@supabase/ssr` and `@supabase/server` coexist and are not replacements for each other, and `@supabase/ssr` is not deprecated. Pick based on where your code runs and how auth reaches it, using the table above.
</Admonition>
## Advanced: Combining `@supabase/server` and `@supabase/ssr`
In a cookie-based framework you can compose the two — let `@supabase/ssr` own the cookie session lifecycle and hand the resolved token to `@supabase/server`'s primitives. This requires more setup, and deeper first-party integration is on the roadmap. See the [`@supabase/server` SSR frameworks guide](https://github.com/supabase/server/blob/main/docs/ssr-frameworks.md).
## Next steps
- [Server-side rendering](/guides/auth/server-side) — set up `@supabase/ssr` for your framework.
- [`@supabase/server` reference](/docs/reference/server) — API for header-based server auth.
- [`supabase-js` reference](/docs/reference/javascript) — the base JavaScript client.
@@ -16,6 +16,11 @@ export const authGetStarted: ContentListingGroup = {
href: '/guides/auth/server-side',
description: 'Create a Supabase client for SSR frameworks like Next.js and SvelteKit.',
},
{
title: 'Which package to use',
href: '/guides/auth/choosing-a-server-package',
description: 'supabase-js vs @supabase/ssr vs @supabase/server — which to use on the server.',
},
{
title: 'Row Level Security',
href: '/guides/database/postgres/row-level-security',
@@ -7,3 +7,5 @@ hideTitle: true
This reference documents every object and method available in Supabase's isomorphic JavaScript library, `supabase-js`. You can use `supabase-js` to interact with your Postgres database, listen to database changes, invoke Deno Edge Functions, build login and user management functionality, and manage large files.
To convert SQL queries to `supabase-js` calls, use the [SQL to REST API translator](/docs/guides/api/sql-to-rest).
Using `supabase-js` on the server? See [which package to use](/docs/guides/auth/choosing-a-server-package) to decide between `supabase-js`, `@supabase/ssr`, and `@supabase/server`.
@@ -6,3 +6,5 @@ title: Introduction
`@supabase/server` is a framework-agnostic library for authenticating requests in server-side JavaScript environments. It verifies JWTs, resolves Supabase API keys, and creates pre-configured Supabase clients — exposing everything through a single `SupabaseContext` that is identical regardless of which adapter or primitive produced it.
Adapters for Hono, H3, Elysia, and NestJS are included. You can also compose the lower-level primitives directly for custom frameworks or edge runtimes.
Not sure this is the right package? See [which package to use](/docs/guides/auth/choosing-a-server-package) — for cookie-based sessions in SSR frameworks, use [`@supabase/ssr`](/docs/guides/auth/server-side) instead.
@@ -6,3 +6,5 @@ title: Introduction
This reference documents every object and method available in Supabase's isomorphic JavaScript library, `supabase-js`. You can use `supabase-js` to interact with your Postgres database, listen to database changes, invoke Deno Edge Functions, build login and user management functionality, and manage large files.
To convert SQL queries to `supabase-js` calls, use the [SQL to REST API translator](/docs/guides/api/sql-to-rest).
Using `supabase-js` on the server? See [which package to use](/docs/guides/auth/choosing-a-server-package) to decide between `supabase-js`, `@supabase/ssr`, and `@supabase/server`.
@@ -6,3 +6,9 @@ title: Introduction
`@supabase/server` is a framework-agnostic library for authenticating requests in server-side JavaScript environments. It verifies JWTs, resolves Supabase API keys, and creates pre-configured Supabase clients — exposing everything through a single `SupabaseContext` that is identical regardless of which adapter or primitive produced it.
Adapters for Hono, H3, Elysia, and NestJS are included. You can also compose the lower-level primitives directly for custom frameworks or edge runtimes.
<Admonition type="note" title="Not sure this is the right package?">
See [which package to use](/docs/guides/auth/choosing-a-server-package) — for cookie-based sessions in SSR frameworks, use [`@supabase/ssr`](/docs/guides/auth/server-side) instead.
</Admonition>
+2
View File
@@ -223,6 +223,7 @@ allow_list = [
"dotenvx",
"Drizzle",
"ElevenLabs",
"Elysia",
"[Ee]nablement",
"EnterpriseDB",
"Entra",
@@ -306,6 +307,7 @@ allow_list = [
"MySQL",
"[Nn]amespaces?",
"[Nn]ano",
"NestJS",
"Netlify",
"Next.js",
"[Nn]ginx",