Library / SDK
supabase/supabase-js avatar
supabase/supabase-js

supabase-js: the isomorphic client behind a Postgres-first backend

An isomorphic Javascript client for Supabase. Query your Supabase database, subscribe to realtime events, upload and download files, browse typescript examples, invoke postgres functions via rpc, invoke supabase edge functions, query pgvector.

4,568 stars750 forksTypeScriptMIT

At a glance

What is it?
The JavaScript SDK that wraps PostgREST, GoTrue, Realtime, Storage and Edge Functions behind one client object. It is a thin layer over HTTP and WebSocket, and that thinness is both its value and its limit.
Who is it for?
Adopt supabase-js if your data already lives in Supabase Postgres and you want auth, realtime and storage through one client, or if you are shipping to browsers, Node.js, Deno, Bun, React Native or Cloudflare Workers from a single codebase. Do not adopt it if you need ORM-level migration tooling, a schema-first type generator that works offline, or a database you do not control.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What supabase-js actually removes from your stack

A Supabase project exposes Postgres through PostgREST, authentication through GoTrue, file storage through a storage service, and pub/sub through Realtime. Each of those is reachable over plain HTTP or WebSocket, but each has its own endpoint shape, headers and error format. supabase-js exists to collapse that into one object you construct once and pass around. The README describes the repository as a monorepo containing the complete suite of Supabase JavaScript SDK, with @supabase/supabase-js as the main isomorphic SDK and separate packages for auth, PostgREST, realtime, storage and functions. The target reader is a frontend or full-stack JavaScript developer who wants a Postgres database with auth and file storage attached, without writing a server tier first. The word isomorphic in the description is doing real work: the same import is meant to run in a browser tab, in a Node.js process, in Deno, in Bun, in React Native and in a Cloudflare Worker.

One client object, six packages, and PostgREST underneath

The architecture is a facade. @supabase/supabase-js sits on top of @supabase/postgrest-js, @supabase/auth-js, @supabase/realtime-js, @supabase/storage-js and @supabase/functions-js, and the main package re-exports their behaviour behind namespaces. Database queries do not speak SQL over a socket. They build a PostgREST request, and PostgREST translates it into SQL against your Postgres instance. That is why the client supports filtering, ordering, embedding related rows and calling stored procedures via rpc rather than exposing a query planner. Realtime subscriptions run over WebSocket, which is why the README states that browsers using realtime features must support the native WebSocket API, on top of the native fetch API required for everything else. The data flow for a normal read is: client method call, PostgREST HTTP request with your project URL and key, SQL execution, JSON response. There is no local query engine and no client-side cache.

Installing supabase-js and running a first insert

The README gives one installation command, and it is the same package for every runtime it supports.

bash
npm install @supabase/supabase-js

That is the only install step the README documents. For wiring the client to a project, it points to the guides and the JavaScript reference docs rather than inlining an example, so the configuration values live there. The repository layout shows the SDK split across packages/core/supabase-js, packages/core/auth-js, packages/core/postgrest-js, packages/core/realtime-js, packages/core/storage-js and packages/core/functions-js, and each package has its own README with the API surface for that namespace. The pattern to notice when you read those docs is that the client returns a result object with data and error rather than throwing. If you are used to try/catch around every call, that is a habit you have to unlearn here. The repository does not document a rollback path for a partially applied multi-statement write, because each call is a separate PostgREST request.

The runtime support policy is the sharpest edge in the repository

This is where supabase-js differs from most client libraries, and where teams get surprised. The README states that only Node.js versions in Active LTS or Maintenance status are supported, and that when a version reaches end-of-life Supabase will drop it in a minor release, and this will not be considered a breaking change. That policy is already spent: Node.js 18 support was dropped in version 2.79.0, with 2.78.0 named as the last version that supported it, and Node.js 20 support was dropped in version 2.110.0, with 2.109.0 named as the last version. Deno, Bun, React Native and Cloudflare Workers are supported on current stable versions with the same minor-release caveat, and those runtimes do not publish a schedule as structured as Node.js. If you pin a caret range and your CI image is on an old Node.js line, a routine dependency bump can take you from working to unsupported without a major version change. Pin exactly, and read the release notes before moving.

Where supabase-js is the wrong tool

The client is a transport, not an ORM. It has no migration system, no schema definition language and no relation graph it can traverse on its own. If your team expects typed models generated from a schema, eager loading across arbitrary relation chains, or a migration diff command, supabase-js does not provide them; the codegen scripts in package.json generate types from the API surface, not from your database schema. The second limit is coupling: every database call is a PostgREST call, so anything PostgREST cannot express is either an rpc call to a Postgres function or a request that leaves the client entirely. The third is that the SDK assumes a Supabase-hosted or self-hosted Supabase project with the REST, auth and realtime services in place. Pointing it at a bare Postgres instance will not work. Finally, the README flags that experimental features may be removed or changed without notice, so anything labelled experimental should not sit under a production write path.

supabase-js versus Prisma and Drizzle

The comparison that matters is not feature count, it is where the query is built. Prisma and Drizzle both put a schema definition in your repository and generate a typed client from it, so the database shape is versioned alongside your application code and migrations are part of the same tool. supabase-js does the opposite: it assumes the database already exists and that PostgREST will describe it, so there is nothing to generate from your side and nothing to migrate. That makes supabase-js faster to start and weaker at schema evolution. Drizzle in particular emits SQL you can read, which matters when a query is slow and you need to understand the plan. With supabase-js, the SQL is produced by PostgREST, and your debugging surface is the HTTP request and the Postgres log. If you already run Supabase and your schema changes rarely, the client is the shorter path. If your schema is the thing under active development, an ORM with migrations is the better fit, and you can still keep Supabase for auth and storage.

Maintenance, release cadence and the MIT licence

The repository is not archived, and the last push was on 2026-09-22. The most recent release listed is v2.117.0 on 2026-09-22, with two canary builds on 2026-09-17 and 2026-09-22, so canary and stable are being cut from the same tree within days of each other. The upgrade cost is concentrated in runtime support rather than API churn: the version-to-Node.js mapping is the thing to track, and the README names the exact last-good versions. The monorepo uses pnpm workspaces with Nx, and package.json sets packageManager to [email protected], so contributing or building from source means matching that toolchain. The licence is MIT, which is permissive and imposes no copyleft obligation on your application; the LICENSE file is at the repository root. That is a statement about the licence text, not advice about your situation, and the SDK's licence does not govern the Supabase services you connect it to.

Editorial conclusion

Adopt supabase-js if your data already lives in Supabase Postgres and you want auth, realtime and storage through one client, or if you are shipping to browsers, Node.js, Deno, Bun, React Native or Cloudflare Workers from a single codebase. Do not adopt it if you need ORM-level migration tooling, a schema-first type generator that works offline, or a database you do not control. Before wiring anything, check the Node.js version in .nvmrc and the release notes for the last version that supported your runtime, because dropping an end-of-life Node.js line happens in a minor release and is not treated as breaking.

Frequently asked questions

How do I install supabase-js?

Install the main package with npm install @supabase/supabase-js. The README lists that as the single installation command and points to the getting started guide and JavaScript reference for setup details.

What is the supabase-js client?

It is an isomorphic JavaScript SDK for Supabase, described in the README as the main package in a monorepo that also contains separate auth, PostgREST, realtime, storage and functions SDKs. It lets you query a Postgres database through PostgREST, subscribe to realtime events, upload files and invoke edge functions from one client object.

How can I use Supabase in React?

You import from @supabase/supabase-js and construct a client with your project URL and key, then call methods from your components. The README states that all modern browsers are supported as long as they provide the native fetch API, and realtime features additionally need native WebSocket support.

supabase-js versus Prisma or Drizzle: how do they differ?

supabase-js sends requests that PostgREST turns into SQL against an existing database, so it ships no schema definition or migration tooling. Prisma and Drizzle generate a typed client from a schema you keep in your repository, which makes them the stronger choice when the schema itself is under active development.

How do I use supabase-js?

You install @supabase/supabase-js, create a client from your project URL and key, and call methods that map to PostgREST requests, realtime subscriptions, storage uploads or edge function invocations. The README points to the guides and the JavaScript reference for the full API surface.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. supabase/supabase-js on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/supabase-supabase-js.svg)](https://hysenlabs.com/projects/supabase-supabase-js)