JSR PUBLISHING
JSR Publishing Setup
This document explains how JSR (JavaScript Registry) publishing is configured in this monorepo.
Overview
Supabase JavaScript packages are published to npm, and select packages with explicit return types are also published to JSR. JSR publishing happens automatically after npm publishing in both stable and canary releases.
Currently, only packages with complete TypeScript typing (explicit return types) are published to JSR to maintain high quality standards and optimal type-checking performance.
Current Status
JSR publishing is configured for packages with explicit return types
The following packages are currently published to JSR:
- @supabase/functions-js (has explicit return types)
- @supabase/supabase-js (has explicit return types)
Authentication
JSR publishing uses OpenID Connect (OIDC) authentication from GitHub Actions, which is the recommended approach by JSR. This means:
- No secrets to manage or rotate
- Automatic authentication via GitHub
- Short-lived tokens for enhanced security
- Works automatically when id-token: write permission is set
The workflow already has the required permissions configured:
permissions:
contents: read
id-token: write # Required for JSR OIDC authenticationNo additional setup is required - JSR publishing works automatically in GitHub Actions.
How It Works
1. Version Synchronization: The jsr.json files use placeholder versions (e.g., "0.0.0" or "0.0.0-automated"). The publish script updates these to match the package.json version before publishing, then restores the original placeholder to keep the working directory clean.
2. OIDC Authentication: When running in GitHub Actions with id-token: write permission, JSR automatically authenticates using GitHub's OIDC tokens. No manual token management is required.
3. Type Checking: Only packages with explicit return types are published to JSR. This ensures optimal performance and aligns with JSR's quality standards.
Published packages (with explicit return types):
- functions-js - Has explicit return types
- supabase-js - Has explicit return types (aggregates other packages)
4. Failure Handling: JSR publishing failures don't fail the entire release - npm releases will still succeed.
Files Involved
- scripts/publish-to-jsr.ts - Main JSR publishing script
- scripts/release-stable.ts - Calls JSR publish after stable npm release
- scripts/release-canary.ts - Calls JSR publish after canary npm release
- packages/core/*/jsr.json - JSR configuration for each package
- .github/workflows/publish.yml - GitHub Actions workflow with OIDC permissions
---
MIGRATION
Migration Guide
Cross-cutting migration notes for the Supabase JavaScript SDK. One H2 section per migration theme.
Per-package migrations (changes scoped to a single SDK like@supabase/auth-js) live alongside the package they affect, underpackages/core/<package>/migrations/. The notes in this file cover changes that span multiple packages or the workspace as a whole.
Edge Functions auth headers
Edge Function calls (supabase.functions.invoke()) now keep the apikey and Authorization headers distinct, matching the Server SDK pattern:
- The API key is always sent in the apikey header.
- Authorization carries the signed-in user's JWT (or a custom auth token). When there is no user session, a new-format API key (sb_publishable_… / sb_secret_…) is no longer sent as Authorization: Bearer <key> — new-format keys are not JWTs, and the gateway now accepts apikey-only requests (including for verify_jwt=true functions).
This does not affect other services (Database/PostgREST, Storage, Realtime), and legacy JWT keys are unchanged (they are still sent in Authorization for backward compatibility).
What to do
Nothing for the vast majority of users — authenticated calls still send the user's JWT, and unauthenticated calls continue to work via the apikey header.
The only impacted case is code that reads the API key out of the Authorization header inside an Edge Function (e.g. a server-side check on Bearer sb_...). Those cases should read the apikey header instead, or migrate to @supabase/server for edge functions.
Node.js 18 support dropped (v2.79.0, 2025-10-31)
Starting with version 2.79.0, all Supabase JavaScript libraries require Node.js 20 or later. The @supabase/node-fetch polyfill has been removed and native fetch is now required.
Affected packages
@supabase/supabase-js, @supabase/auth-js, @supabase/postgrest-js, @supabase/realtime-js, @supabase/storage-js, @supabase/functions-js.
Why
Node.js 18 reached end-of-life on April 30, 2025 and no longer receives security updates. Node.js 20+ ships with native fetch, eliminating the need for the polyfill and reducing bundle size.
What to do
1. Upgrade Node.js to version 20 or later:
# Check current version
node --version # Via nvm
nvm install 20
nvm use 20
# Or download from https://nodejs.org/
2. Update your dependencies:
npm install @supabase/supabase-js@latest
# or, per-package:
npm install @supabase/auth-js@latest3. No code changes required — APIs are unchanged.
Supported runtimes
- Node.js 20+ (native fetch)
- Modern browsers
- Deno 2.x
- Bun 0.1+
- React Native and Expo (with the framework's bundled fetch polyfill)
Troubleshooting
fetch is not defined — you're on Node.js < 20. Upgrade Node.js. If you absolutely cannot upgrade, pin to the last version that supported Node.js 18:
npm install @supabase/[email protected]⚠️ Using Node.js 18 is not recommended — it no longer receives security updates.
Reference
---
RELEASE
Release Workflows
TL;DR: master is the default branch. Every push auto-publishes a @canary prerelease; stable releases are manually promoted from master. v3 is a long-lived feature branch for v3-only (breaking) work; v3 prereleases (@next) are published manually via workflow_dispatch. Beta and preview paths are unchanged.
Branch model
| Branch | Role | Default? | PR target for |
| -------- | ------------------------------------------ | -------- | ---------------------------------- |
| master | v2 active development, @canary/@latest | Yes | All work (features, fixes, chores) |
| v3 | v3 breaking changes, @next (manual) | No | v3-only breaking changes |
graph LR
master["master (default)"] -- "auto on push" --> canary["@canary"]
master -- "manual" --> latest["@latest"]
v3["v3"] -- "manual" --> next["@next"]
feature["feature/*"] -- "manual" --> beta["@beta"]v3 is kept in sync with master by periodic manual merge (no automation):
git switch v3 && git pull --ff-only
git merge master # merge commit, NOT rebase
resolve conflicts, favor v3 for breaking-change code paths
git push origin v3Release types
All packages share a single version (fixed versioning).
| Type | Trigger | Branch | npm tag | Version | Script |
| ----------- | ----------- | ----------- | -------- | ---------------- | ------------------- |
| Canary | Auto (push) | master | canary | 2.x.x-canary.X | release-canary.ts |
| Stable | Manual | master | latest | 2.x.x | release-stable.ts |
| Next | Manual | v3 | next | 3.0.0-next.X | release-canary.ts |
| Beta | Manual | feature/* | beta | x.x.x-beta.X | release-beta.ts |
| Preview | Auto (PR) | any | - | - | pkg.pr.new |
Canary (auto)
Every push to master runs publish.yml and publishes a canary if there are conventional commits since the last stable tag:
| Commit type | Bump |
| ---------------------------- | ----- |
| fix: | patch |
| feat: | minor |
| feat!: / BREAKING CHANGE | major |
Skipped if no conventional commits are detected. Install: npm install @supabase/supabase-js@canary.
Stable, Next, Beta (manual)
All three are paths inside publish.yml's workflow_dispatch. Trigger from Actions → Publish releases → Run workflow, select the branch, fill exactly one input, leave the others empty:
| Path | Branch | Input to fill |
| ------ | ----------- | ------------------------------------------------------- |
| Stable | master | version_specifier (e.g. patch, minor, v2.105.0) |
| Next | v3 | check next_prerelease |
| Beta | feature/* | beta_version (e.g. 2.105.0-beta.0) |
Restricted to @supabase/admin or @supabase/sdk team members. Each path posts to Slack on success/failure.
The Next path reads .next-base-version (currently 3.0.0) and auto-computes the next -next.X suffix. The GitHub release is auto-marked as a prerelease (nx detects the semver prerelease identifier); npm dist-tag is next, not latest.
npm install @supabase/supabase-js@next # v3 prerelease
npm install @supabase/supabase-js@beta # beta from a feature branchPreview (PR-based)
Every PR that touches packages/core/ auto-publishes via pkg.pr.new (preview-release.yml). No label needed.
npm install https://pkg.pr.new/@supabase/supabase-js@[commit-hash]Common flows
Non-breaking fix or feature: PR → master → canary auto-publishes → trigger Stable when ready → optionally merge master into v3 to bring the change forward.
v3-only breaking change: PR → v3 (no auto-publish) → manually trigger Next when a prerelease is needed for dogfooding.
Emergency v2 fix: PR → master → trigger Stable with patch → merge master into v3 so it carries forward.
v3 ships: PR v3 → master (merge commit), then trigger Stable with major → publishes 3.0.0 with latest.
Configuration
- .next-base-version — base version for v3 prereleases
- scripts/release-canary.ts — canary (default) + next (via --base-version, --preid, --tag flags)
- scripts/release-stable.ts — stable releases, creates the changelog PR
- scripts/release-beta.ts — beta from feature branches
Permissions
- Automated canary uses a GitHub App token (must be a bypass actor on master)
- Manual releases (Stable, Next, Beta) require @supabase/admin or @supabase/sdk membership
- npm uses OIDC trusted publishing (provenance); all paths live in publish.yml
- Slack failure notifications post to #team-sdk
---
TESTING
Testing Guide
This monorepo uses Nx for orchestrating tests across all packages. Each package has its own testing requirements and infrastructure.
Quick Start
To run tests for any package:
Complete test suites (recommended - handles Docker automatically)
pnpm nx test:auth auth-js # Complete auth-js test suite
pnpm nx test:storage storage-js # Complete storage-js test suite
pnpm nx test:ci:postgrest postgrest-js # Complete postgrest-js test suite
pnpm nx test functions-js # Standard test (uses testcontainers)
pnpm nx test realtime-js # Standard test (no Docker needed)
pnpm nx test supabase-js # Standard test (unit tests only)E2E tests (require local Supabase running — see E2E section below)
pnpm nx test:e2e auth-js # Auth-js Playwright e2e tests
pnpm nx test:e2e realtime-js # Realtime-js Playwright e2e testsPackage-Specific Testing Guides
Each package has unique testing requirements. Please refer to the individual README files for detailed instructions:
Core Packages
| Package | Docker Required | Test Command | Documentation |
| ---------------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------------------------------- |
| auth-js | ✅ Yes (GoTrue + PostgreSQL) | pnpm nx test:auth auth-js | Testing Guide |
| functions-js | ✅ Yes (Deno relay via testcontainers) | pnpm nx test functions-js | Testing Guide |
| postgrest-js | ✅ Yes (PostgREST + PostgreSQL) | pnpm nx test:ci:postgrest postgrest-js | Testing Guide |
| realtime-js | ❌ No (uses mock WebSockets) | pnpm nx test realtime-js | Testing Guide |
| storage-js | ✅ Yes (Storage API + PostgreSQL + Kong) | pnpm nx test:storage storage-js | Testing Guide |
| supabase-js | ❌ No (unit tests only) | pnpm nx test supabase-js | Testing Guide |
Coverage Commands
Run tests with coverage
pnpm nx test supabase-js --coverage
pnpm nx test:coverage realtime-js
pnpm nx test:ci functions-js # Includes coverageE2E Tests (Playwright)
The auth-js and realtime-js packages include Playwright end-to-end tests that run against their example apps and a local Supabase instance.
Prerequisites
- Supabase running locally — Start the local Supabase stack via the supabase-js setup target:
pnpm nx test:supabase:setup supabase-js- Playwright Chromium — Installed automatically by the
test:e2e target (no separate install needed).Environment Variables
Each example directory ships with a .env.local.ci file pre-configured for the default local Supabase instance (http://127.0.0.1:54321). The test:e2e target copies this file to .env.local automatically.
If you're using a custom local Supabase setup, create .env.local manually in the example directory:
| Package | Directory | Variables |
| ------------- | -------------------------------------- | ------------------------------------------------------------------ |
| auth-js | packages/core/auth-js/example/react/ | VITE_SUPABASE_URL, VITE_SUPABASE_PUBLISHABLE_DEFAULT_KEY |
| realtime-js | packages/core/realtime-js/example/ | NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY |
Running E2E Tests
Run individually
pnpm nx test:e2e auth-js
pnpm nx test:e2e realtime-jsRun both sequentially (avoids port conflicts)
pnpm nx run-many --target=test:e2e --projects=auth-js,realtime-js --parallel=1Note: Run with --parallel=1 when running both together — the apps use different ports (5173 and 3000) but share the same local Supabase, and sequential execution avoids potential resource conflicts.What the Tests Cover
| Package | Test file | Scenarios |
| ------------- | ---------------------------------------- | --------------------------------------------------------------------------- |
| auth-js | example/react/tests/auth-flows.spec.ts | Sign-up, sign-in, sign-out, anonymous auth, magic link, session persistence |
| realtime-js | example/tests/chat.spec.ts | Send messages, room switching, broadcast between clients, presence |
Playwright Reports
On failure, test traces and screenshots are saved locally. In CI, Playwright HTML reports are uploaded as workflow artifacts.
Prerequisites
- Node.js 20+ - Required for all packages
- Docker - Required for auth-js, functions-js, postgrest-js, and storage-js
- Ports - Various packages use different ports for test infrastructure (see individual READMEs)
CI Testing
In CI environments, tests are run automatically using GitHub Actions. The CI pipeline:
1. Sets up Node.js and Docker
2. Installs dependencies
3. Runs tests for all affected packages
4. Generates coverage reports
For CI-specific test commands, many packages have a test:ci target that includes coverage reporting.
Troubleshooting
For package-specific issues, consult the troubleshooting section in each package's README. Common issues:
- Port conflicts: Check if required ports are already in use
- Docker not running: Ensure Docker Desktop is started
- Container cleanup: Use pnpm nx test:clean-post <package> if containers weren't properly removed
Contributing Tests
When adding new features or fixing bugs:
1. Write tests that cover your changes
2. Ensure all existing tests pass
3. Update test documentation if you change testing infrastructure
4. Follow the testing patterns established in each package
For more details on contributing, see CONTRIBUTING.md.
---
CHANGELOG
2.112.3 (2026-08-11)
🩹 Fixes
- supabase: add trace context headers to canonical CORS allow-list (#2603)
- supabase: improve trace propagation sampling and diagnostics (#2604)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.112.2 (2026-08-06)
🩹 Fixes
- realtime: prevent duplicate on bindings (#2594)
- realtime: clear stale join payload on sign-out (#2597)
❤️ Thank You
- Filipe Cabaço @filipecabaco
- Vaibhav @7ttp
2.112.1 (2026-08-05)
🩹 Fixes
- auth: preserve 5xx error message (#2587)
- realtime: ensure setAuth doesn't disable token refresh (#2592)
❤️ Thank You
- Eduardo Gurgel
- Vaibhav @7ttp
2.112.0 (2026-08-03)
🚀 Features
- supabase: move OpenTelemetry tracing to opt-in /tracing subpath (#2583)
🩹 Fixes
- auth: accept uppercase UUIDs in validateUUID (#2467)
- postgrest: honour throwOnError when maybeSingle finds multiple rows (#2580)
- storage: resolve createSignedUrls return type mismatch (#2474)
- storage: expose service error code on StorageApiError (#2537)
- supabase: forward db retry option (#2571)
❤️ Thank You
- Anubhav Anand @i-anubhav-anand
- Gourab Singha @gourabsingha1
- Juhef @juheff
- Katerina Skroumpelou @mandarini
- Thribhuvan
- Vaibhav @7ttp
- Zuhef Ahmed @Zuhef
2.111.0 (2026-07-28)
🚀 Features
- auth: store PKCE verifiers in per-flow slots to survive overlapping flows (#2569)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.110.9 (2026-07-27)
🩹 Fixes
- auth: downgrade stale refresh token console noise (#2559)
- realtime: preserve presence refs (#2566)
- repo: override sharp to >=0.35.0 to clear libvips advisory (#2548)
- repo: populate symbols in sdk-compliance so capabilities are verifiable (#2547)
- repo: bump postcss, babel, next to clear audit advisories (#2561)
❤️ Thank You
- Katerina Skroumpelou @mandarini
- Vaibhav @7ttp
2.110.8 (2026-07-21)
🩹 Fixes
- auth: downgrade aborted/transient fetch failures from console.error to warn (#2544)
- functions: clean up cross-signal abort listener on invoke() return (#2487)
- functions: match response Content-Type case-insensitively (#2515)
- storage: url-encode object key in CDN purge methods (#2545)
- supabase: skip Node warning in Deno (#2541)
❤️ Thank You
- Franco Kaddour @FrancoKaddour
- Katerina Skroumpelou @mandarini
- Pedro Henrique
- Vaibhav @7ttp
2.110.7 (2026-07-16)
🩹 Fixes
- postgrest: correct self-reference inference (#2525)
- realtime: trigger set auth on INITIAL_SESSION event (#2531)
- realtime: update phoenix to fix presence issue (#2532)
❤️ Thank You
- Eduardo Gurgel
- Filipe Cabaço @filipecabaco
- Vaibhav @7ttp
2.110.6 (2026-07-15)
🩹 Fixes
- postgrest: type hinted self-referencing embeds as arrays (#2520)
- realtime: forward opts to send() in track() (#2490)
- supabase: warn instead of throw for unrecognized sb_ API key subtypes (#2526)
❤️ Thank You
- Franco Kaddour @FrancoKaddour
- Katerina Skroumpelou @mandarini
2.110.5 (2026-07-14)
🩹 Fixes
- supabase: avoid edge runtime warning (#2522)
❤️ Thank You
- Vaibhav @7ttp
2.110.4 (2026-07-14)
🩹 Fixes
- functions: stop sending API key in Authorization header for function calls (#2511)
- realtime: encode broadcast header fields as UTF-8 (#2516)
❤️ Thank You
- Katerina Skroumpelou @mandarini
- Pedro Henrique
2.110.3 (2026-07-13)
🩹 Fixes
- auth: preserve pkce verifier (#2513)
- postgrest: pin tstyche target off floating latest (#2509)
❤️ Thank You
- Katerina Skroumpelou @mandarini
- Vaibhav @7ttp
2.110.2 (2026-07-09)
🩹 Fixes
- auth: clear local session on signout failures (#2504)
❤️ Thank You
- Luc Peng
2.110.1 (2026-07-07)
🩹 Fixes
- auth: defer init-time notifications until initializePromise resolves (#2498)
- realtime: suppress disconnected status from onHeartbeat consumers (#2496)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.110.0 (2026-06-30)
🚀 Features
- repo: drop Node.js 20 support (#2482)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.109.0 (2026-06-30)
🚀 Features
- auth: add custom_claims_allowlist to custom providers admin API (#2473)
- realtime: add postgres_changes filter builder, new operators and select (#2463)
- storage: expose purgeCache for buckets and single objects (#2429)
🩹 Fixes
- functions: honor a caller's Content-Type override regardless of casing (#2455)
- realtime: pin @supabase/phoenix and browser test CDN deps (#2457)
- realtime: add replication connection system message option (#2470)
- storage: keep sortBy defaults when list() is given a partial sortBy (#2454)
❤️ Thank You
- Anubhav Anand @i-anubhav-anand
- Cemal Kılıç @cemalkilic
- Claude Opus 4.8 (1M context)
- Filipe Cabaço @filipecabaco
- Katerina Skroumpelou @mandarini
- Lenny
- Rodrigo Mansueli @mansueli
2.108.2 (2026-06-15)
🩹 Fixes
- auth: preserve valid session on refresh failure and cooldown repeat failures (#2436)
- realtime: clarify httpSend() 404 error and server migration note (#2444)
- release: pin Deno and bound JSR publish to survive stranded-task hangs (#2439)
- release: restore JSR publish flags and enable for beta (#2440)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.108.0 (2026-06-08)
🚀 Features
- auth: auth.resend() consistent confirmation flow (#2144)
🩹 Fixes
- auth: do not console.error AuthApiError already returned through contract (#2428)
- postgrest: pass request headers as plain object for RN/custom-fetch compatibility (#2414)
❤️ Thank You
- Katerina Skroumpelou @mandarini
- Lawrence Li @weilirs
- MaitreyeeDeshmukh
2.107.0 (2026-06-02)
🚀 Features
- auth: remove navigator.locks-based mutex; introduce commit guard + dispose() (#2392)
- realtime: allow httpSend to send binary payload (#2400)
- supabase: update X-Client-Info to structured metadata format (#2359)
🩹 Fixes
- auth: return AuthInvalidJwtError from getClaims for expired JWT (#2395)
- auth: recognize ?error= redirects in implicit grant gate (#2407)
- auth): revert fix(auth: encode client-id in oauth requests (#2383, #2417)
- postgrest: return a structured error for non-JSON body on successful responses (#2398)
- release: pin workspace:* sibling deps before JSR publish (#2418)
- release: publish gotrue-js legacy mirror via pnpm (#2419)
❤️ Thank You
- Claude Opus 4.7 (1M context)
- Claude Sonnet 4.6
- Eduardo Gurgel
- Guilherme Souza
- Katerina Skroumpelou @mandarini
- Omar Al Matar @Bewinxed
- youcef zr @youcefzemmar
- youcefzemmar
2.106.2 (2026-05-25)
🩹 Fixes
- auth: restore signup user response (#2391)
- misc: add react-native export condition for Hermes-safe resolution (#2393)
❤️ Thank You
- Myroslav Hryhschenko @BLOCKMATERIAL
- Vaibhav @7ttp
2.106.1 (2026-05-20)
🩹 Fixes
- auth: encode client-id in oauth requests (#2383)
- misc: hide dynamic import from hermesc (#2381)
❤️ Thank You
- Etienne Stalmans @staaldraad
- Katerina Skroumpelou @mandarini
2.106.0 (2026-05-18)
🚀 Features
- supabase: W3C/OpenTelemetry trace context propagation (#2163)
🩹 Fixes
- auth: return null user and session for email_change single-confirmation verifyOtp (#2378)
- release: mark @supabase/tracing private and snapshot it for JSR (#2370)
- storage: make StreamDownloadBuilder implement Promise and memoize executor (#2367)
❤️ Thank You
- Claude Sonnet 4.5
- Guilherme Souza
- Katerina Skroumpelou @mandarini
- oniani1
2.105.4 (2026-05-08)
🩹 Fixes
- auth: return null from getItemAsync on JSON parse failure (#2336)
- postgrest: restore non-Error abort detection in fetch catch (#2335)
- realtime: guard sessionStorage access in restricted-storage browsers (#2339)
2.105.2 (2026-05-04)
🩹 Fixes
- auth: forward lockAcquireTimeout to SupabaseAuthClient (#2309)
- auth: add toJSON to WebAuthnError for correct JSON serialization (#2317)
- misc: widen enum-like unions with (string & {}) for forward compat (#2303)
- misc: reduce any usage across packages (#2314)
- postgrest: unify insert/upsert signatures (#2315)
❤️ Thank You
- Muzzaiyyan Hussain @MuzzaiyyanHussain
2.105.1 (2026-04-28)
🩹 Fixes
- postgrest: query reassignment regression (#2292)
- realtime: surface real Error on transport-level CHANNEL_ERROR (#2299)
❤️ Thank You
- Vaibhav @7ttp
2.105.0 (2026-04-27)
🚀 Features
- auth: add passkey support with WebAuthn registration, authentication, and management (#2283)
- realtime: Realtime deferred disconnect (#2282)
🩹 Fixes
- postgrest: narrow column types after not(column, is, null) (#2264)
- realtime: annotate Timer/Vsn getters to avoid deep phoenix imports (#2284)
- storage: apply metadata, headers, and cacheControl dedupe to uploadToSignedUrl (#2275)
- storage: forward duplex option for stream uploads via uploadToSignedUrl (#2289)
❤️ Thank You
- Katerina Skroumpelou @mandarini
- oniani1
2.104.1 (2026-04-23)
🩹 Fixes
- auth: emit PASSWORD_RECOVERY event for PKCE recovery flows (#2272)
- postgrest: restore runtime test files to tstyche scope (#2266)
- supabase: propagate custom fetch to realtime client (#2267)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.104.0 (2026-04-20)
🚀 Features
- storage: extract shared header normalization utility (#2251)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.103.3 (2026-04-16)
🩹 Fixes
- realtime: throw Error objects instead of bare strings (#2256)
- storage: correct signedUrl type to allow null in createSignedUrls (#2254)
❤️ Thank You
- Katerina Skroumpelou @mandarini
- oniani1
2.103.2 (2026-04-15)
🩹 Fixes
- auth: include Cloudflare error codes in NETWORK_ERROR_CODES (#2239)
- auth: remove Prettify wrapper from exported types for TypeDoc expansion (#2250)
- misc: add explicit return types to toJSON methods for JSR compat (#2252)
- storage: remove client-side signed URL render endpoint normalization (#2249)
❤️ Thank You
- Katerina Skroumpelou @mandarini
- Vansh Sharma @Vansh1811
2.103.1 (2026-04-15)
🩹 Fixes
- auth: add toJSON to AuthError for correct JSON serialization (#2238)
- postgrest: handle bigint rpc (#2245)
- storage: add toJSON to StorageError for correct JSON serialization (#2246)
- storage: apply empty transform check to download and getPublicUrl (#2219)
❤️ Thank You
- oniani1
- Vaibhav @7ttp
2.103.0 (2026-04-09)
🚀 Features
- postgrest: add stripNulls method for null value stripping (#2189)
- storage: add cacheNonce parameter for download (#2234)
🩹 Fixes
- postgrest: fix scalar computed column type inference for isNotNullable and SETOF scalar (#2224)
❤️ Thank You
- Katerina Skroumpelou @mandarini
- Seydi Charyyev @TheSeydiCharyyev
- Vaibhav @7ttp
2.102.1 (2026-04-07)
🩹 Fixes
- functions: add toJSON to FunctionsError for correct JSON serialization (#2226)
❤️ Thank You
- oniani1
2.102.0 (2026-04-07)
🚀 Features
- postgrest: add automatic retries for transient errors (#2072)
- postgrest: add success discriminator field to PostgREST response types (#2198)
- supabase: export PostgrestFilterBuilder and StorageApiError from supabase-js (#2222)
🩹 Fixes
- auth: downgrade console.error to console.warn for missing session (#2214)
- ci: add --ignore-scripts to platform test installs to block post install attacks (#2206)
- postgrest: add toJSON to PostgrestError for correct JSON serialization (#2212)
- postgrest: reject excess properties in insert, update, and upsert (#2186)
- storage: set correct content-type for uploads (#2211)
- storage: avoid duplicate content-type headers in vector requests (#2220)
❤️ Thank You
- Clay
- Guilherme Souza
- Katerina Skroumpelou @mandarini
- oniani1
- Vaibhav @7ttp
2.101.1 (2026-03-31)
🩹 Fixes
- storage: support exactOptionalPropertyTypes (#2200)
❤️ Thank You
- Vaibhav @7ttp
2.101.0 (2026-03-30)
🚀 Features
- realtime: add copyBindings functionality (#2197)
- realtime: block setting postgres_changes event listener after joining (#2201)
❤️ Thank You
- Dominik Pilipczuk @snickerdoodle2
2.100.1 (2026-03-26)
🩹 Fixes
- postgrest: add type safety for eq() and neq() column names (#2175)
- postgrest: fix maybeSingle for all request methods by removing Accept header override (#2182)
- postgrest: narrow tstyche testFileMatch to only type test files (#2193)
- postgrest: prevent Args: never functions from being classified as computed fields (#2195)
- storage: spread all DEFAULT_FILE_OPTIONS in uploadToSignedUrl (#2194)
❤️ Thank You
- Ayush Baluni @aayushbaluni
- Katerina Skroumpelou @mandarini
2.100.0 (2026-03-23)
🚀 Features
- realtime: use phoenix's js lib inside realtime-js (#2119)
🩹 Fixes
- auth: guard navigator lock steal against cascade when lock is stolen by another request (#2178)
- realtime: revert vsn type to string (#2170)
- storage: structural detection on json() to detect Response-like errors (#2179)
❤️ Thank You
- Alan Guzek @GuzekAlan
- Dominik Pilipczuk @snickerdoodle2
- Katerina Skroumpelou @mandarini
2.99.2 (2026-03-16)
🩹 Fixes
- storage: do not rewrite signed URL to render endpoint for empty transform object (#2162)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.99.1 (2026-03-11)
🩹 Fixes
- functions: add RateLimitError in Deno.errors namespace (#2160)
❤️ Thank You
- 냥냐챠 @nyannyacha
2.99.0 (2026-03-09)
🚀 Features
- auth: add custom OIDC/OAuth provider admin CRUD methods (#2133)
🩹 Fixes
- storage: improve FileObject type accuracy with nullable fields (#2116)
❤️ Thank You
- Cemal Kılıç @cemalkilic
- Katerina Skroumpelou @mandarini
2.98.0 (2026-02-26)
🚀 Features
- auth: add token_endpoint_auth_method to OAuth client create/update (#2132)
- auth: support custom providers via custom: prefix in Provider type (#2134)
- auth: add currentPassword to UserAttributes type (#2131)
🩹 Fixes
- auth: recover from orphaned navigator locks via steal fallback (#2106)
- auth: lower lockAcquireTimeout default to 5s and fix stale JSDoc (#2125)
- auth: fixes userattributes type (#2139)
- realtime: patch channel join payloads with resolved access token before flushing send buffer (#2136)
❤️ Thank You
- Cemal Kılıç @cemalkilic
- Elliot Padfield @ElliotPadfield
- Etienne Stalmans @staaldraad
- Katerina Skroumpelou @mandarini
2.97.0 (2026-02-18)
🚀 Features
- auth: add skipAutoInitialize option to prevent constructor auto-init (#2123)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.96.0 (2026-02-17)
🚀 Features
- storage: add setHeader method to BaseApiClient (#2079)
🩹 Fixes
- auth: resolve Firefox content script Promise.then() security errors in locks (#2112)
- postgrest: enforce type safety for table and view names in from() method (#2058)
- realtime: remove unnecessary check in removeChannel (#2109)
❤️ Thank You
- David Barrell @dabarrell
- Dominik Pilipczuk @snickerdoodle2
- Katerina Skroumpelou @mandarini
- Vaibhav @7ttp
2.95.3 (2026-02-06)
🚀 Features
- supabase: add canonical CORS headers export for edge functions (#2071)
🩹 Fixes
- realtime: removeChannel when unsubscribe successfully (#2091)
- storage: expose fetch parameters in download method (#2090)
❤️ Thank You
- Eduardo Gurgel
- Katerina Skroumpelou @mandarini
2.95.0 (2026-02-05)
🚀 Features
- supabase: add canonical CORS headers export for edge functions (#2071)
🩹 Fixes
- realtime: removeChannel when unsubscribe successfully (#2091)
- storage: expose fetch parameters in download method (#2090)
❤️ Thank You
- Eduardo Gurgel
- Katerina Skroumpelou @mandarini
2.94.1 (2026-02-04)
🩹 Fixes
- auth: correct OAuth authorization types to match API responses (#2088)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.94.0 (2026-02-03)
🚀 Features
- postgrest: add URL length validation and timeout protection (#2078)
🩹 Fixes
- ci: handle missing git auth header in release-canary script (#2077)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.93.3 (2026-01-29)
🩹 Fixes
- auth: add webauthn tests and fix fallback naming (#1763)
- ci: add persist-credentials: false to release job checkouts (#2074)
- storage: handle empty 200 responses in vector operations (#2073)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.93.2 (2026-01-27)
🩹 Fixes
- supabase: revert client platform and runtime detection headers (#2067)
❤️ Thank You
- Guilherme Souza
2.93.1 (2026-01-26)
🩹 Fixes
- realtime: revert validate table filter in postgres_changes event dispatch (#2060)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.93.0 (2026-01-26)
🚀 Features
- auth: add optional jwt parameter to getAuthenticatorAssuranceLevel (#1940)
- supabase: add missing HTTP headers for client platform and runtime detection (#2046)
🩹 Fixes
- auth: handle uncaught promise rejections during initialization (#2032)
- auth: clear local storage on signOut when session is already missing (#2026)
- realtime: send heartbeat for initial connection error (#1746)
- realtime: add generic overload for postgres_changes event type (#1984)
- storage: expose status and statusCode on StorageError base class (#2018)
- supabase: safe environment detection node v browser (#2053)
❤️ Thank You
- Katerina Skroumpelou @mandarini
- Vaibhav @7ttp
2.91.1 (2026-01-23)
🩹 Fixes
- auth: restore SSR OAuth functionality broken in v2.91.0 (#2039)
❤️ Thank You
- Vaibhav @7ttp
2.91.0 (2026-01-20)
🚀 Features
- realtime: set default serializer to 2.0.0 (#2034)
🩹 Fixes
- auth: defer subscriber notification in exchangeCodeForSession to prevent deadlock (#2014)
- auth: clarify updateUserById applies changes directly (#2031)
- supabase: resolve Firefox extension cross-context Promise error (#2033)
❤️ Thank You
- Eduardo Gurgel
- Vaibhav @7ttp
2.90.1 (2026-01-08)
🩹 Fixes
- postgrest: prevent shared state between query builder operations (#1978)
- realtime: validate table filter in postgres_changes event dispatch (#1999)
❤️ Thank You
- Vaibhav @7ttp
2.90.0 (2026-01-07)
🚀 Features
- realtime: expose heartbeat latency on heartbeat callback (#1982)
🩹 Fixes
- auth: add banned_until property to user type (#1989)
- auth: add last_challenged_at property to factor type (#1990)
- auth: clear initial setTimeout in stopAutoRefresh (#1993)
- auth: preserve session when magic link is clicked twice (#1996)
- auth: add configurable lock acquisition timeout to prevent deadlocks (#1962)
- functions: auto-stringify object body when custom Content-Type header is provided (#1988)
- postgrest: use post with return minimal for rpc head requests with object args (#1994)
- supabase: split type-only exports to avoid unused import warnings (#1979)
- supabase: inline string literal in databasewithoutinternals type (#1986)
- supabase: avoid edge runtime warnings in next.js (#1998)
❤️ Thank You
- Eduardo Gurgel
- Nico Kempe @nicokempe
- Vaibhav @7ttp
- yoshifumi kondo @yoshifumi-kondo
2.89.0 (2025-12-18)
🚀 Features
- auth: add X (OAuth 2.0) provider (#1960)
- auth: add string array support for AMR claims (#1967)
- supabase: export DatabaseWithoutInternals utility type (#1935)
❤️ Thank You
- Cemal Kılıç @cemalkilic
- issuedat @issuedat
- Vaibhav @7ttp
2.88.0 (2025-12-16)
🚀 Features
- auth: allow custom predicate for detectSessionInUrl option (#1958)
- postgrest: add notin filter (#1957)
- repo: migrate build system to tsdown for proper ESM/CJS support (#1961)
🩹 Fixes
- realtime: handle websocket race condition in node.js (#1946)
- realtime: omit authorization header when no access token exists (#1937)
❤️ Thank You
- Katerina Skroumpelou @mandarini
- Vaibhav @7ttp
2.87.3 (2025-12-15)
🩹 Fixes
- supabase: resolve jsDelivr CDN ESM import failure with .js extensions (#1953)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.87.2 (2025-12-15)
🩹 Fixes
- auth: add helpful error when PKCE code verifier is missing (#1931)
- realtime: terminate web worker on disconnect to prevent memory leak (#1907)
- supabase: resolve jsDelivr CDN ESM import failure (#1950)
❤️ Thank You
- Katerina Skroumpelou @mandarini
- Tanmay Sharma @tanmaysharma2001
2.87.1 (2025-12-09)
🩹 Fixes
- auth: skip navigator lock when persistSession is false (#1928)
- realtime: preserve custom JWT tokens across channel resubscribe (#1908)
- realtime: handle null values in postgres changes filter comparison (#1918)
❤️ Thank You
- Liam
- Vaibhav @7ttp
2.87.0 (2025-12-08)
🚀 Features
- storage: align analytics from method with { data, error } pattern (#1927)
🩹 Fixes
- repo: update lock file after dependabot to use npm 11 (#1926)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.86.2 (2025-12-04)
🩹 Fixes
- storage: correct QueryVectorsResponse to use vectors instead of matches (#1922)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.86.1 (2025-12-04)
🩹 Fixes
- auth: suppress getsession warning when getuser is called first (#1898)
- auth: code verifier remains in storage during edge cases (#1759)
- postgrest: cross-schema rpc setof type inference (#1900)
- repo: update lock file (#1910)
- repo: lock file issues (#1919)
- repo: update npm and install again (#1920)
- supabase: add esm wrapper to resolve module not found error in nuxt (#1914)
❤️ Thank You
- Katerina Skroumpelou @mandarini
- Vaibhav @7ttp
2.86.0 (2025-11-26)
🚀 Features
- storage: install iceberg-js and add from method (#1881)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.85.0 (2025-11-26)
🚀 Features
- realtime: add metadata to realtime user broadcast push (#1894)
🩹 Fixes
- auth: oauth minor fixes on types (#1891)
❤️ Thank You
- Cemal Kılıç @cemalkilic
- Eduardo Gurgel
2.84.0 (2025-11-20)
🚀 Features
- postgrest: add isdistinct and regex pattern matching operators (#1875)
🩹 Fixes
- postgrest: validate empty or invalid relation names in Postgrest… (#1863)
- realtime: simplify serializer by removing unnecessary types of messages (#1871)
❤️ Thank You
- Eduardo Gurgel
- Katerina Skroumpelou @mandarini
- Soufiane Radouane @sofmega
2.83.0 (2025-11-18)
🚀 Features
- storage: rename StorageAnalyticsApi to StorageAnalyticsClient (#1869)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.82.0 (2025-11-18)
🚀 Features
- auth: add OAuth grant listing and revocation endpoints (#1833)
🩹 Fixes
- postgrest: bubble up fetch error causes and codes (#1856)
- realtime: account for null refs when encoding messages (#1862)
- storage: analytics bucket prop (#1852)
❤️ Thank You
- Cemal Kılıç @cemalkilic
- Eduardo Gurgel
- Fabrizio @fenos
- Katerina Skroumpelou @mandarini
2.81.1 (2025-11-11)
🩹 Fixes
- auth: use Symbols for callback IDs to resolve Next.js 16 compatibility (#1847)
- auth: add automatic browser redirect to signInWithSSO (#1849)
- realtime: setAuth not required on custom jwt token (#1826)
❤️ Thank You
- Filipe Cabaço @filipecabaco
- Katerina Skroumpelou @mandarini
2.81.0 (2025-11-10)
🚀 Features
- realtime: implement V2 serializer (#1829)
🩹 Fixes
- auth: make webauthn param optional and move register params to webauthn (#1765)
- auth: add providers type to UserAppMetadata interface (#1760)
- auth: use direct attestation for registration/authentication (#1764)
- functions: add configurable timeout and normalize abort/timeout errors as FunctionsFetchError (#1837)
- realtime: ensure WebSocket connections are properly closed in teardown (#1841)
❤️ Thank You
- Eduardo Gurgel
- Katerina Skroumpelou @mandarini
- Tanmay Sharma @tanmaysharma2001
2.80.0 (2025-11-06)
🚀 Features
- auth: add TypeScript types for documented JWT claims fields (#1802)
🩹 Fixes
- auth: only warn if multiple clients share a storage-key (#1767)
❤️ Thank You
- Steve Hall @sh41
- Sumit Kumar @Software-Engineering-Project-Team-Bob
2.79.0 (2025-11-04)
🚀 Features
- auth: support throwing errors instead of returning them (#1766)
- repo: remove node-fetch dependency, require Node.js 20+ (#1830)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.78.0 (2025-10-30)
🚀 Features
- auth: add OAuth 2.1 authorization consent management API calls (#1793)
- auth: add OAuth client update support (#1812)
- auth: refactor getAuthenticatorAssuranceLevel method (#1822)
🩹 Fixes
- auth: remove redirection in getAuthorizationDetails (#1811)
- auth: move session warning proxy from session to user object (#1817)
❤️ Thank You
- Cemal Kılıç @cemalkilic
- Katerina Skroumpelou @mandarini
- Stojan Dimitrovski @hf
2.77.0 (2025-10-29)
🚀 Features
- auth: add OAuth 2.1 authorization consent management API calls (#1793)
- auth: add OAuth client update support (#1812)
- storage: add support for bucket pagination and sorting (#1790)
🩹 Fixes
- auth: handle 204 No Content response in OAuth client delete (#1786)
- auth: remove redirection in getAuthorizationDetails (#1811)
- postgrest: add incoming major 14 support (#1807)
- repo: add missing tslib dependency to core packages (#1789)
- repo: cleanup package-lock.json and bun.lock (#1799)
- storage: remove unnecessary filter (#1809)
🔥 Performance
- precompile RegExp (#1806)
❤️ Thank You
- Andrew Valleteau @avallete
- Cemal Kılıç @cemalkilic
- Fabrizio @fenos
- Katerina Skroumpelou @mandarini
- Kevin Grüneberg @kevcodez
- Lenny @itslenny
2.76.1 (2025-10-21)
🩹 Fixes
- repo: add missing tslib dependency to core packages (#1789)
❤️ Thank You
- Katerina Skroumpelou @mandarini
2.76.0 (2025-10-20)
🚀 Features
- realtime: realtime explicit REST call (#1751)
- realtime: enhance RealtimeChannel type (#1747)
- storage: storage vectors and analytics in storage-js (#1752)
🩹 Fixes
- functions: missing body when Content-Type header supplied by dev (#1758)
- functions: add application/pdf response parsing to FunctionsClient (#1757)
- realtime: manipulate URLs using URL object (#1769)
- repo: convert postbuild to explicit codegen (#1778)
- storage: correct list v2 types to correctly match data returned from api (#1761)
- storage: use backward compatible return type in download function (#1750)
- storage: api types (#1784)
❤️ Thank You
- Fabrizio @fenos
- Filipe Cabaço @filipecabaco
- Guilherme Souza
- Katerina Skroumpelou @mandarini
- Lenny @itslenny
2.75.1 (2025-10-17)
🩹 Fixes
- storage: use backward compatible return type in download function (#1750)
❤️ Thank You
- Lenny @itslenny
2.75.0 (2025-10-09)
🚀 Features
- postgrest: add embeded functions type inference (#1632)
❤️ Thank You
- Andrew Valleteau @avallete
2.74.0 (2025-10-07)
🚀 Features
- auth: add deprecation notice to onAuthStateChange with async function (#1580)
- auth: add OAuth 2.1 client admin endpoints (#1582)
- docs: explicitly mark options as optional (#1622)
- realtime: add support to configure Broadcast Replay (#1623)
- release: enable trusted publishing (#1592)
- storage: add support for sorting to list v2 (#1606)
🩹 Fixes
- storage: remove trailing slash from baseUrl normalization (#1589)
❤️ Thank You
- Cemal Kılıç @cemalkilic
- Doğukan Akkaya
- Eduardo Gurgel
- Etienne Stalmans @staaldraad
- Lenny @itslenny
- Stojan Dimitrovski @hf
- Taketo Yoshida
---
CONTRIBUTING
Contributing to Supabase JS Libraries
Thank you for your interest in contributing to the Supabase JavaScript SDK! This guide will help you get started with contributing to the Supabase JS monorepo.
📋 Table of Contents
- Getting Started
- Development Workflow
- Commit Guidelines
- Pull Request Process
- Testing
- Documentation
- Release Process
- Getting Help
Getting Started
Prerequisites
- Node.js (version 20 or higher)
- pnpm (enable via corepack enable — the workspace pins the version in package.json)
- Docker (required for integration tests)
- Git
Initial Setup
1. Fork the repository on GitHub
2. Clone your fork locally:
git clone [email protected]:YOUR_USERNAME/supabase-js.git
cd supabase-js3. Install dependencies:
corepack enable
pnpm install4. Build all packages:
pnpm nx run-many --target=build --all5. Run tests to ensure everything works:
pnpm nx affected --target=testBrowser tests (optional)
The test:integration:browser target for supabase-js uses Puppeteer. The workspace denies arbitrary install scripts by default, so Puppeteer does not download Chromium during pnpm install. If you want to run browser tests locally, install Chrome once:
pnpm exec puppeteer browsers install chromeCI does this explicitly after pnpm install, so it's only a manual step for local browser testing.
Development Workflow
Making Changes
1. Create a new branch from master (the default branch — features, fixes, and chores all start here). Branch from v3 only when working on v3-only breaking changes:
git checkout master
git pull upstream master
git checkout -b feature/your-feature-name
# or
git checkout -b fix/your-bug-fix v3-only breaking changes target the v3 branch directly. The v3 branch is kept in sync with master periodically via a maintainer-run merge — no per-PR action needed from contributors.
2. Make your changes in the appropriate library under packages/core/
3. Follow our coding standards:
- Use TypeScript for all new code
- Follow existing code style and patterns
- Add JSDoc comments for public APIs
- Use meaningful commit messages (see Commit Guidelines)
4. Test your changes:
# Run affected tests
pnpm nx affected --target=test # Run specific library tests
pnpm nx test <package-name>
For detailed testing instructions, see TESTING.md and the README in each package directory.
5. Format your code:
pnpm nx format6. Build affected packages:
pnpm nx affected --target=buildCommit Guidelines
We use Conventional Commits with automated tooling to ensure consistent commit messages and enable automatic versioning.
Using the Interactive Commit Tool
You can use the interactive commit tool instead of git commit directly:
pnpm commitThis command will:
- Guide you through creating a properly formatted commit message
- Validate your commit against our rules
- Ensure all required fields are filled out correctly
- Prevent invalid commits from being created
Commit Message Format
All commits must follow this format:
<type>(<scope>): <description>[optional body]
[optional footer(s)]
Available Types
| Type | Description |
| ---------- | ------------------------------------------------------------- |
| feat | A new feature |
| fix | A bug fix |
| docs | Documentation only changes |
| style | Changes that do not affect the meaning of the code |
| refactor | A code change that neither fixes a bug nor adds a feature |
| perf | A code change that improves performance |
| test | Adding missing tests or correcting existing tests |
| build | Changes that affect the build system or external dependencies |
| ci | Changes to our CI configuration files and scripts |
| chore | Other changes that don't modify src or test files |
| revert | Reverts a previous commit |
Available Scopes
#### Library-Specific Scopes
- auth - Changes to @supabase/auth-js
- functions - Changes to @supabase/functions-js
- postgrest - Changes to @supabase/postgrest-js
- realtime - Changes to @supabase/realtime-js
- storage - Changes to @supabase/storage-js
- supabase - Changes to @supabase/supabase-js
#### Workspace-Level Scopes
- repo - Repository-level changes
- deps - Dependencies
- ci - Changes to CI
- release - Release process
- docs - Documentation
- scripts - Build/dev scripts
- misc - Miscellaneous
Commit Examples
feat(auth): add support for custom auth providers
fix(storage): resolve upload timeout issue
docs(postgrest): update filter documentation
chore(deps): update nx to latest version
ci(release): add preview package generationImportant Notes
- Scope is required - Every commit must have a scope
- Use imperative mood - "add feature" not "added feature"
- Keep subject line under 100 characters
- No period at the end of the subject line
- Use the interactive tool - pnpm commit ensures compliance
Pull Request Process
Before Submitting
1. Ensure your branch is up to date with the branch you're targeting (typically master; v3 only for v3-only breaking changes):
git checkout <target-branch> # master or v3
git pull upstream <target-branch>
git checkout your-branch
git rebase <target-branch>2. Run the full test suite:
pnpm nx affected --target=test3. Build all affected packages:
pnpm nx affected --target=buildSubmitting Your PR
1. Push your branch to your fork:
git push origin your-branch-name2. Create a Pull Request on GitHub with:
- Clear title describing the change
- Detailed description of what was changed and why
- Reference any related issues
- Screenshots or examples if applicable
PR Requirements
All pull requests must meet these requirements:
- ✅ At least 1 approving review from a code owner
- ✅ All status checks passing (CI/CD pipeline)
- ✅ No merge conflicts with the base branch
- ✅ Squash merge only (enforced by repository settings)
Review Process
1. Automated checks will run (linting, testing, building)
2. Code owners will be automatically requested for review
3. Address feedback by pushing new commits to your branch
4. Resolve all conversations before merge
Testing
Each package has its own testing requirements and infrastructure. For comprehensive testing information, see:
- TESTING.md - Overview of testing across all packages
- Package-specific guides - Detailed testing instructions in each package's README:
- supabase-js
- auth-js
- functions-js
- postgrest-js
- realtime-js
- storage-js
Quick Testing Commands
Run tests for a specific package
pnpm nx test <package-name>Run affected tests only (recommended during development)
pnpm nx affected --target=testRun tests with coverage
pnpm nx test <package> --coverageTest Requirements by Package
| Package | Docker Required | Details |
| ------------ | --------------- | ---------------------------------------------------------- |
| auth-js | ✅ Yes | See README |
| functions-js | ✅ Yes | See README |
| postgrest-js | ✅ Yes | See README |
| realtime-js | ❌ No | See README |
| storage-js | ✅ Yes | See README |
| supabase-js | ❌ No\* | See README |
\*supabase-js integration tests require additional setup
Documentation
TypeScript API Documentation
We automatically generate TypeScript API documentation that is used by the main Supabase documentation site. The process works as follows:
1. TypeDoc generates JSON specifications from TypeScript source code
2. GitHub Actions publishes these specs to GitHub Pages after every successful stable release from master
3. Main Supabase repository uses these JSON files to generate the official API docs via make commands
#### Available Documentation Commands
Generate JSON specs for all libraries (used by main docs)
pnpm nx run-many --target=docs:json --allGenerate HTML docs for all libraries (for local viewing)
pnpm nx run-many --target=docs --allGenerate docs for a specific library
pnpm nx docs:json auth-js
pnpm nx docs postgrest-js#### Published API Specifications
When contributing changes that affect public APIs, the documentation will be automatically updated when your PR is merged.
Release Process
Fixed Version Mode
All packages in this monorepo use fixed version mode, meaning they share the same version number and are released together. This ensures compatibility and simplifies dependency management.
Testing Releases
If you need to test your changes with a release build, you can use pkg.pr.new:
1. Create a PR with your changes
2. Comment on the PR and tag a maintainer, asking them to add the trigger: preview label
3. A maintainer will add the label to trigger the preview release
4. Use the generated package URLs to test your changes in other projects
This allows you to test package changes without waiting for an official release, while ensuring preview releases are controlled by maintainers.
Official Releases
Official releases are handled by maintainers using Nx Release. You can read more in the RELEASE.md
Getting Help
Resources
- Documentation: supabase.com/docs
- Community: GitHub Discussions
- Issues: GitHub Issues
- Discord: Supabase Discord
Reporting Issues
When reporting issues, please include:
1. Clear description of the problem
2. Steps to reproduce the issue
3. Expected vs actual behavior
4. Environment information (Node.js version, library versions, etc.)
5. Code examples or minimal reproduction cases
Asking Questions
- General questions: Use GitHub Discussions
- Bug reports: Use GitHub Issues
- Feature requests: Use GitHub Issues with the "enhancement" label
🤝 Code of Conduct
We are committed to providing a welcoming and inspiring community for all. Please review our Code of Conduct before participating.
📄 License
By contributing to Supabase JS Libraries, you agree that your contributions will be licensed under the MIT License.
---
Thank you for contributing to Supabase! 💚
---
README
<br />
<p align="center">
<a href="https://supabase.io">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/supabase-logo-wordmark--dark.svg">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/supabase-logo-wordmark--light.svg">
<img alt="Supabase Logo" width="300" src="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/logo-preview.jpg">
</picture>
</a>
<h1 align="center">Supabase JS SDK</h1>
<p align="center">
<a href="https://supabase.com/docs/guides/getting-started">Guides</a>
·
<a href="https://supabase.com/docs/reference/javascript/introduction">Reference Docs</a>
</p>
</p>
<div align="center">
[](https://github.com/supabase/supabase-js/actions?query=branch%3Amaster)
[](https://www.npmjs.com/package/@supabase/postgrest-js)
[](#license)
[](https://pkg.pr.new/~/supabase/supabase-js)
</div>
📦 Libraries
This monorepo contains the complete suite of Supabase JavaScript SDK:
| Library | Description |
| ---------------------------------------------------------- | ------------------------------------- |
| @supabase/supabase-js | Main isomorphic SDK for Supabase |
| @supabase/auth-js | Authentication SDK |
| @supabase/postgrest-js | PostgREST SDK for database operations |
| @supabase/realtime-js | Real-time subscriptions SDK |
| @supabase/storage-js | File storage SDK |
| @supabase/functions-js | Edge Functions SDK |
Support Policy
This section outlines the scope of support for various runtime environments in Supabase JavaScript client.
Node.js
We only support Node.js versions that are in Active LTS or Maintenance status as defined by the official Node.js release schedule. This means we support versions that are currently receiving long-term support and critical bug fixes.
When a Node.js version reaches end-of-life and is no longer in Active LTS or Maintenance status, Supabase will drop it in a minor release, and this won't be considered a breaking change.
⚠️ Node.js 18 Deprecation Notice
> Node.js 18 reached end-of-life on April 30, 2025. As announced in our deprecation notice, support for Node.js 18 was dropped in version 2.79.0.> If you must use Node.js 18, please use version 2.78.0, which is the last version that supported Node.js 18.⚠️ Node.js 20 Deprecation Notice
> Node.js 20 reached end-of-life on April 30, 2026. As announced in our deprecation notice, support for Node.js 20 was dropped in version 2.110.0.> If you must use Node.js 20, please use version 2.109.0, which is the last version that supported Node.js 20.Deno
We support Deno versions that are currently receiving active development and security updates. We follow the official Deno release schedule and only support versions from the stable and lts release channels.
When a Deno version reaches end-of-life and is no longer receiving security updates, Supabase will drop it in a minor release, and this won't be considered a breaking change.
Browsers
All modern browsers are supported. We support browsers that provide native fetch API. For Realtime features, browsers must also support native WebSocket API.
Bun
We support Bun runtime environments. Bun provides native fetch support and is compatible with Node.js APIs. Since Bun does not follow a structured release schedule like Node.js or Deno, we support current stable versions of Bun and may drop support for older versions in minor releases without considering it a breaking change.
React Native
We support React Native environments with fetch polyfills provided by the framework. Since React Native does not follow a structured release schedule, we support current stable versions and may drop support for older versions in minor releases without considering it a breaking change.
Cloudflare Workers
We support Cloudflare Workers runtime environments. Cloudflare Workers provides native fetch support. Since Cloudflare Workers does not follow a structured release schedule, we support current stable versions and may drop support for older versions in minor releases without considering it a breaking change.
Important Notes
- Experimental features: Features marked as experimental may be removed or changed without notice
- Build warnings: If you see UNUSED_EXTERNAL_IMPORT warnings from Vite/Nuxt, see the supabase-js README — these are false positives
🚀 Quick Start
Installation
npm install @supabase/supabase-jsRead more in each package's README file.
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
Quick Contribution Steps
1. Fork the repository
2. Create a feature branch (git checkout -b feature/amazing-feature)
3. Make your changes and add tests
4. Run tests (pnpm nx affected --target=test)
5. Commit your changes (pnpm commit)
6. Push to your branch (git push origin feature/amazing-feature)
7. Open a Pull Request
Development Guidelines
- Follow conventional commits for commit messages
- Add tests for new functionality
- Update documentation for API changes
- Run pnpm nx format before committing
- Ensure all tests pass with pnpm nx affected --target=test
🧪 Testing
Testing varies per package. See the top-level TESTING.md for an overview and links to package-specific guides.
📚 Documentation
API Documentation
- Auth SDK - Authentication and user management
- Database SDK - Database queries and operations
- Realtime SDK - Real-time subscriptions
- Storage SDK - File upload and management
- Functions SDK - Edge Functions invocation
- Main SDK - Combined SDK
Architecture Documentation
- Contributing - Development guidelines
- Release Workflows - Release and publishing process
- Migration Guide - Cross-cutting migration notes (per-package migrations live alongside each package under packages/core/<package>/migrations/)
- Security Policy - Vulnerability reporting and disclosure policy
- Securing your npm installs - Consumer-side guide to defending your install against npm supply-chain attacks
🔐 Verifying provenance attestations
You can verify registry signatures and provenance attestations for installed packages using the npm CLI:
npm audit signaturesQuick example for a single package install:
npm install @supabase/auth-js
npm audit signaturesExample output:
audited 1 package in 0s1 package has a verified registry signature
Because provenance attestations are a new capability, security features may evolve over time. Ensure you are using the latest npm CLI to verify attestation signatures reliably. This may require updating npm beyond the version bundled with Node.js.
For a broader checklist — minimum release age, lockfile hygiene, blocking exotic transitive deps, lifecycle script controls, and what to do if you suspect a compromise — see Securing your npm installs.
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🆘 Support
- Documentation: supabase.com/docs
- Community: GitHub Discussions
- Issues: GitHub Issues
- Discord: Supabase Discord
---
<div align="center">
Website • Documentation • Community • Twitter
</div>
---