JavaScript: Upgrade guide

supabase-js v2 focuses on "quality-of-life" improvements for developers and addresses some of the largest pain points in v1. v2 includes type support, a rebuilt Auth library with async methods, improved errors, and more.

No new features will be added to supabase-js v1 , but we'll continuing merging security fixes to v1, with maintenance patches for the next 3 months.

Upgrade the client library

Install the latest version

npm install @supabase/supabase-js@2

Optionally if you are using custom configuration with createClient then follow below:

const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, \{
  schema: 'custom',
  persistSession: false,
\})
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, \{
  db: \{
    schema: 'custom',
  \},
  auth: \{
    persistSession: true,
  \},
\})

Read more about the constructor options.

Auth methods

The signIn() method has been deprecated in favor of more explicit method signatures to help with type hinting. Previously it was difficult for developers to know what they were missing (e.g., a lot of developers didn't realize they could use passwordless magic links).

Sign in with email and password

const \{ user, error \} = await supabase
  .auth
  .signIn(\{ email, password \})
const \{
  data: \{ user \},
  error,
\} = await supabase
  .auth
  .signInWithPassword(\{ email, password \})

Sign in with magic link

const \{ error \} = await supabase
  .auth
  .signIn(\{ email \})
const \{ error \} = await supabase
  .auth
  .signInWithOtp(\{ email \})

Sign in with a third-party provider

const \{ error \} = await supabase
  .auth
  .signIn(\{ provider \})
const \{ error \} = await supabase
  .auth
  .signInWithOAuth(\{ provider \})

Sign in with phone

const \{ error \} = await supabase
  .auth
  .signIn(\{ phone, password \})
const \{ error \} = await supabase
  .auth
  .signInWithPassword(\{ phone, password \})

Sign in with phone using OTP

const \{ error \} = await supabase
  .auth
  .api
  .sendMobileOTP(phone)
const \{ data, error \} = await supabase
  .auth
  .signInWithOtp(\{ phone \})
  
// After receiving a SMS with a OTP.
const \{ data, error \} = await supabase
  .auth
  .verifyOtp(\{ phone, token \})

Reset password for email

const \{ data, error \} = await supabase
  .auth
  .api
  .resetPasswordForEmail(email)
const \{ data, error \} = await supabase
  .auth
  .resetPasswordForEmail(email)

Get the user's current session

const session = supabase.auth.session()
const \{
  data: \{ session \},
\} = await supabase.auth.getSession()

Get the logged-in user

const user = supabase.auth.user()
const \{
  data: \{ user \},
\} = await supabase.auth.getUser()

Update user data for a logged-in user

const \{ user, error \} = await supabase
  .auth
  .update(\{ attributes \})
const \{
  data: \{ user \},
  error,
\} = await supabase.auth.updateUser(\{ attributes \})

Use a custom access_token JWT with Supabase

const \{ user, error \} = supabase.auth.setAuth(access_token)
const supabase = createClient(
  SUPABASE_URL,
  SUPABASE_ANON_KEY,
  \{
    global: \{
      headers: \{
        Authorization: `Bearer $\{access_token\}`,
      \},
    \},
  \}
)

Cookie methods

The cookie-related methods like setAuthCookie and getUserByCookie have been removed.

For Next.js you can use the Auth Helpers to help you manage cookies. If you can't use the Auth Helpers, you can use server-side rendering.

Some the PR for additional background information.

Data methods

.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.

Insert and return data

const \{ data, error \} = await supabase
  .from('my_table')
  .insert(\{ new_data \})
const \{ data, error \} = await supabase
  .from('my_table')
  .insert(\{ new_data \})
  .select()

Update and return data

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

Upsert and return data

const \{ data, error \} = await supabase
  .from('my_table')
  .upsert(\{ new_data \})
const \{ data, error \} = await supabase
  .from('my_table')
  .upsert(\{ new_data \})
  .select()

Delete and return data

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

Realtime methods

Subscribe

const userListener = supabase
  .from('users')
  .on('*', (payload) => handleAllEventsPayload(payload.new))
  .subscribe()
const userListener = supabase
  .channel('public:user')
  .on('postgres_changes', \{ event: '*', schema: 'public', table: 'user' \}, (payload) =>
    handleAllEventsPayload()
  )
  .subscribe()

Unsubscribe

userListener.unsubscribe()
supabase.removeChannel(userListener)