---
title: Supabase Storage
description: Supabase Storage via @supabase/storage-js. Pass an existing SupabaseClient to share auth/postgrest with the rest of your app.
peerDeps:
  - "@supabase/storage-js"
---

## Installation

`@supabase/storage-js` is an optional peer dependency of `files-sdk` - install alongside the SDK so the adapter's imports resolve at runtime.

```package-install
files-sdk @supabase/storage-js
```

## Usage

Supabase Storage via the official `@supabase/storage-js` SDK. Auto-loads the project URL and an API key from the standard env vars; pass `client` to share an existing `SupabaseClient` with the rest of your app (auth, postgrest).

```ts lineNumbers
import { Files } from "files-sdk";
import { supabase } from "files-sdk/supabase";

const files = new Files({
  adapter: supabase({
    bucket: "uploads",
    // Auto-loads url + key from SUPABASE_URL / NEXT_PUBLIC_SUPABASE_URL
    // and SUPABASE_SERVICE_ROLE_KEY / SUPABASE_KEY /
    // NEXT_PUBLIC_SUPABASE_ANON_KEY. Or pass an existing SupabaseClient
    // via `client` to share with auth/postgrest.
  }),
});
```

## Options

<AutoTypeTable
  path="../../packages/files-sdk/src/supabase/index.ts"
  name="SupabaseAdapterOptions"
/>

## Compatibility

| Method            | Status | Notes                                                                                                                                                                                                                                                                                                                                  |
| ----------------- | :----: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `upload`          |   ✅   |                                                                                                                                                                                                                                                                                                                                        |
| `download`        |   ✅   |                                                                                                                                                                                                                                                                                                                                        |
| `delete`          |   ✅   |                                                                                                                                                                                                                                                                                                                                        |
| `list`            |   ⚠️   | Supabase's stable list API is offset/limit, not cursor-based. The adapter encodes the next offset as a numeric cursor string so the unified API works unchanged - the cursor is opaque to callers but is just `String(offset + page)` underneath.                                                                                      |
| `search`          |   ⚠️   | Built on `listAll` — inherits this adapter's `list` behavior above. Client-side key match (glob, regex, substring, exact).                                                                                                                                                                                                             |
| `head`            |   ✅   |                                                                                                                                                                                                                                                                                                                                        |
| `exists`          |   ✅   |                                                                                                                                                                                                                                                                                                                                        |
| `copy`            |   ✅   |                                                                                                                                                                                                                                                                                                                                        |
| `url`             |   ⚠️   | Default mints a signed read URL via `createSignedUrl` (1-hour default). With `public: true`, returns the permanent unsigned `getPublicUrl` result. With `publicBaseUrl`, returns `<publicBaseUrl>/<key>`. `responseContentDisposition` is honored - it threads through Supabase's `download` option in the signed path.                |
| `signedUploadUrl` |   ⚠️   | PUT URL only - Supabase has no POST policy equivalent. `maxSize` throws (Supabase signed upload URLs have no `content-length-range` policy; set the bucket-level size limit in the dashboard instead). `expiresIn` is silently ignored - Supabase fixes the TTL at 2 hours server-side. The returned headers include `x-upsert: true`. |
