---
id: release-notes
---

# Release Notes

Supabase.js v2 release notes.

## 2.0.0

Install the latest with `npm install @supabase/supabase-js`.

### Explicit constructor options

All client specific options within the constructor are keyed to the library: [PR](https://github.com/supabase/supabase-js/pull/458):

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

```ts
// v2 - definitions are injected in `createClient()`
import type { Database } from './DatabaseDefinitions'
const supabase = createClient<Database>(SUPABASE_URL, ANON_KEY)
const { data } = await supabase.from('messages').select().match({ id: 1 })

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

Types can be generated via the CLI:

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

### Data operations return minimal

`.insert()` / `.upsert()` / `.update()` / `.delete()` don't return rows by default: [PR](https://github.com/supabase/postgrest-js/pull/276).

Previously, these methods return inserted/updated/deleted rows by default (which caused [some confusion](https://github.com/supabase/supabase/discussions/1548)), 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.:

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

### New ordering defaults

`.order()` now defaults to Postgres’s default: [PR](https://github.com/supabase/postgrest-js/pull/283).

Previously `nullsFirst` defaults to `false` , meaning `null`s 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.

```jsx
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`

```jsx
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()`, `signInWithPasswordless()`, and `signInWithOtp()`.

```ts
// v2
const { data } = await supabase.auth.signInWithPassword({
  email: 'hello@example',
  password: 'pass',
})
// v1
const { data } = await supabase.auth.signIn({
  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.

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

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

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

### Deprecated setAuth()

Deprecated and removed `setAuth()` . To set a custom `access_token` jwt instead, pass the custom header into the `createClient()` method provided: ([PR](https://github.com/supabase/gotrue-js/pull/340))

### All changes

- `supabase-js`
  - `shouldThrowOnError` has been removed until all the client libraries support this option ([PR](https://github.com/supabase/supabase-js/pull/490)).
- `postgrest-js`
  - TypeScript typings have been reworked [PR](https://github.com/supabase/postgrest-js/pull/279)
  - Use `undefined` instead of `null` for function params, types, etc. (https://github.com/supabase/postgrest-js/pull/278)
  - Some features are now obsolete: (https://github.com/supabase/postgrest-js/pull/275)
    - filter shorthands (e.g. `cs` vs. `contains`)
    - `body` in response (vs. `data`)
    - `upsert`ing through the `.insert()` method
    - `auth` method on `PostgrestClient`
    - client-level `throwOnError`
- `gotrue-js`
  - `supabase-js` client allows passing a `storageKey` param which will allow the user to set the key used in local storage for storing the session. By default, this will be namespace-d with the supabase project ref. ([PR](https://github.com/supabase/supabase-js/pull/460))
  - `signIn` method is now split into `signInWithPassword` , `signInWithPasswordless` , `signInWithOAuth` ([PR](https://github.com/supabase/gotrue-js/pull/304))
  - Deprecated and removed `session()` , `user()` in favour of using `getSession()` instead. `getSession()` will always return a valid session if a user is already logged in, meaning no more random logouts. ([PR](https://github.com/supabase/gotrue-js/pull/299))
  - Deprecated and removed setting for `multitab` support because `getSession()` and gotrue’s reuse interval setting takes care of session management across multiple tabs ([PR](https://github.com/supabase/gotrue-js/pull/366))
  - No more throwing of random errors, gotrue-js v2 always returns a custom error type: ([PR](https://github.com/supabase/gotrue-js/pull/341))
    - `AuthSessionMissingError`
      - Indicates that a session is expected but missing
    - `AuthNoCookieError`
      - Indicates that a cookie is expected but missing
    - `AuthInvalidCredentialsError`
      - Indicates that the incorrect credentials were passed
  - Renamed the `api` namespace to `admin` , the `admin` namespace will only contain methods that should only be used in a trusted server-side environment with the service role key
  - Moved `resetPasswordForEmail` , `getUser` and `updateUser` to the `GoTrueClient` which means they will be accessible from the `supabase.auth` namespace in `supabase-js` instead of having to do `supabase.auth.api` to access them
  - Removed `sendMobileOTP` , `sendMagicLinkEmail` in favor of `signInWithOtp`
  - Removed `signInWithEmail`, `signInWithPhone` in favor of `signInWithPassword`
  - Removed `signUpWithEmail` , `signUpWithPhone` in favor of `signUp`
  - Replaced `update` with `updateUser`
- `storage-js`
  - Return types are more strict. Functions types used to indicate that the data returned could be null even if there was no error. We now make use of union types which only mark the data as null if there is an error and vice versa. ([PR](https://github.com/supabase/storage-js/pull/60))
  - The `upload` and `update` function returns the path of the object uploaded as the `path` parameter. Previously the returned value had the bucket name prepended to the path which made it harder to pass the value on to other storage-js methods since all methods take the bucket name and path separately. We also chose to call the returned value `path` instead of `Key` ([PR](https://github.com/supabase/storage-js/pull/75))
  - `getPublicURL` only returns the public URL inside the data object. This keeps it consistent with our other methods of returning only within the data object. No error is returned since this method cannot does not throw an error ([PR](https://github.com/supabase/storage-js/pull/93))
  - signed urls are returned as `signedUrl` instead of `signedURL` in both `createSignedUrl` and `createSignedUrls` ([PR](https://github.com/supabase/storage-js/pull/94))
  - Encodes URLs returned by `createSignedUrl`, `createSignedUrls` and `getPublicUrl` ([PR](https://github.com/supabase/storage-js/pull/86))
  - `createsignedUrl` used to return a url directly and and within the data object. This was inconsistent. Now we always return values only inside the data object across all methods. ([PR](https://www.notion.so/LW5-supabase-js-v2-7b0bfcdf571d4f20b9b7a9308883f24b))
  - `createBucket` returns a data object instead of the name of the bucket directly. ([PR](https://github.com/supabase/storage-js/pull/89))
  - Fixed types for metadata ([PR](https://github.com/supabase/storage-js/pull/90))
  - Better error types make it easier to track down what went wrong quicker.
  - `SupabaseStorageClient` is no longer exported. Use `StorageClient` instead. ([PR](https://github.com/supabase/storage-js/pull/92)).
- `realtime-js`
  - `RealtimeSubscription` class no longer exists and replaced by `RealtimeChannel`.
  - `RealtimeClient`'s `disconnect` method now returns type of `void` . It used to return type of `Promise<{ error: Error | null; data: boolean }`.
  - Removed `removeAllSubscriptions` and `removeSubscription` methods from `SupabaseClient` class.
  - Removed `SupabaseRealtimeClient` class.
  - Removed `SupabaseQueryBuilder` class.
  - Removed `SupabaseEventTypes` type.
    - Thinking about renaming this to something like `RealtimePostgresChangeEvents` and moving it to `realtime-js` v2.
  - Removed `.from(’table’).on(’INSERT’, () ⇒ {}).subscribe()` in favor of new Realtime client API.
- `functions-js`
  - supabase-js v1 only threw an error if the fetch call itself threw an error (network errors, etc) and not if the function returned HTTP errors like 400s or 500s. We have changed this behaviour to return an error if your function throws an error.
  - We have introduced new error types to distinguish between different kinds of errors. A `FunctionsHttpError` error is returned if your function throws an error, `FunctionsRelayError` if the Supabase Relay has an error processing your function and `FunctionsFetchError` if there is a network error in calling your function.
  - The correct content-type headers are automatically attached when sending the request if you don’t pass in a `Content-Type` header and pass in an argument to your function. We automatically attach the content type for `Blob`, `ArrayBuffer`, `File`, `FormData` ,`String` . If it doesn’t match any of these we assume the payload is `json` , we serialise the payload as JSON and attach the content type as `application/json`.
  - `responseType` does not need to be explicitly passed in. We parse the response based on the `Content-Type` response header sent by the function. We support parsing the responses as `text`, `json`, `blob`, `form-data` and are parsed as `text` by default.
