JavaScript: Release Notes

Supabase.js v2 release notes.

Install the latest version of @supabase/supabase-js

  npm install @supabase/supabase-js

Explicit constructor options

All client specific options within the constructor are keyed to the library.

See PR:

  const supabase = createClient(apiURL, apiKey, \{
    db: \{
      schema: 'public',
    \},
    auth: \{
      storage: AsyncStorage,
      autoRefreshToken: true,
      persistSession: true,
      detectSessionInUrl: true,
    \},
    realtime: \{
      channels,
      endpoint,
    \},
    global: \{
      fetch: customFetch,
      headers: DEFAULT_HEADERS,
    \},
  \})

TypeScript support

The libraries now support typescript.

  // previously definitions were injected in the `from()` method
  supabase.from<Definitions['Message']>('messages').select('\*')

  import type \{ Database \} from './DatabaseDefinitions'

  // definitions are injected in `createClient()`
  const supabase = createClient<Database>(SUPABASE_URL, ANON_KEY)

  const \{ data \} = await supabase.from('messages').select().match(\{ id: 1 \})

Types can be generated via the CLI:

supabase start
supabase gen types typescript --local > DatabaseDefinitions.ts

Data operations return minimal

.insert() / .upsert() / .update() / .delete() don't return rows by default: PR.

Previously, these methods return inserted/updated/deleted rows by default (which caused some confusion), and you can opt to not return it by specifying returning: 'minimal'. Now the default behavior is to not return rows. To return inserted/updated/deleted rows, add a .select() call at the end, e.g.:

const \{ data, error \} = await supabase
    .from('my_table')
    .delete()
    .eq('id', 1)
    .select()

New ordering defaults

.order() now defaults to Postgres’s default: PR.

Previously nullsFirst defaults to false , meaning nulls are ordered last. This is bad for performance if e.g. the column uses an index with NULLS FIRST (which is the default direction for indexes).

Cookies and localstorage namespace

Storage key name in the Auth library has changed to include project reference which means that existing websites that had their JWT expiry set to a longer time could find their users logged out with this upgrade.

const defaultStorageKey = `sb-$\{new URL(this.authUrl).hostname.split('.')[0]\}-auth-token`

New Auth Types

Typescript typings have been reworked. Session interface now guarantees that it will always have an access_token, refresh_token and user

interface Session \{
  provider_token?: string | null
  access_token: string
  expires_in?: number
  expires_at?: number
  refresh_token: string
  token_type: string
  user: User
\}

New Auth methods

We're removing the signIn() method in favor of more explicit function signatures: signInWithPassword(), signInWithOtp(), and signInWithOAuth().

  const \{ data \} = await supabase.auth.signIn(\{
    email: 'hello@example',
    password: 'pass',
  \})

  const \{ data \} = await supabase.auth.signInWithPassword(\{
    email: 'hello@example',
    password: 'pass',
  \})

New Realtime methods

There is a new channel() method in the Realtime library, which will be used for our Multiplayer updates.

We will deprecate the .from().on().subscribe() method previously used for listening to postgres changes.

supabase
  .channel('any_string_you_want')
  .on('presence', \{ event: 'track' \}, (payload) => \{
    console.log(payload)
  \})
  .subscribe()

supabase
  .channel('any_string_you_want')
  .on(
    'postgres_changes',
    \{
      event: 'INSERT',
      schema: 'public',
      table: 'movies',
    \},
    (payload) => \{
      console.log(payload)
    \}
  )
  .subscribe()

Deprecated setAuth()

Deprecated and removed setAuth() . To set a custom access_token jwt instead, pass the custom header into the createClient() method provided: (PR)

All changes