All skills
Skillintermediate

Build the package

<br /> <p align="center"> <a href="https://supabase.io"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/supabase-logo-wordmark--dark.svg"> <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/supabase-logo

Claude Code Knowledge Pack7/10/2026

Overview

<br /> <p align="center"> <a href="https://supabase.io"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/supabase-logo-wordmark--dark.svg"> <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/supabase-logo-wordmark--light.svg"> <img alt="Supabase Logo" width="300" src="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/logo-preview.jpg"> </picture> </a> <h1 align="center">Supabase Storage JS SDK</h1> <h3 align="center">JavaScript SDK to interact with Supabase Storage, including file storage and vector embeddings.</h3> <p align="center"> <a href="https://supabase.com/docs/guides/storage">Guides</a> · <a href="https://supabase.com/docs/reference/javascript/storage-createbucket">Reference Docs</a> · <a href="https://supabase.github.io/supabase-js/storage-js/v2/spec.json">TypeDoc</a> </p> </p> <div align="center">

Build Package License: MIT pkg.pr.new

</div>

Requirements

  • Node.js 20 or later (Node.js 18 support dropped as of October 31, 2025)
  • For browser support, all modern browsers are supported

⚠️ Node.js 18 Deprecation Notice

Node.js 18 reached end-of-life on April 30, 2025. As announced in our deprecation notice, support for Node.js 18 was dropped on October 31, 2025.

Features

  • File Storage: Upload, download, list, move, and delete files
  • Access Control: Public and private buckets with fine-grained permissions
  • Signed URLs: Generate time-limited URLs for secure file access
  • Image Transformations: On-the-fly image resizing and optimization
  • Vector Embeddings: Store and query high-dimensional embeddings with similarity search
  • Analytics Buckets: Iceberg table-based buckets optimized for analytical queries and data processing

Quick Start Guide

Installing the module

npm install @supabase/storage-js

Connecting to the storage backend

There are two ways to use the Storage SDK:

Option 1: Via Supabase Client (Recommended)

If you're already using @supabase/supabase-js, access storage through the client:


// Use publishable/anon key for frontend applications
const supabase = createClient('https://<project_ref>.supabase.co', '<your-publishable-key>')

// Access storage
const storage = supabase.storage

// Access different bucket types
const regularBucket = storage.from('my-bucket')
const vectorBucket = storage.vectors.from('embeddings-bucket')
const analyticsBucket = storage.analytics // Analytics API

Option 2: Standalone StorageClient

For backend applications or when you need to bypass Row Level Security:


const STORAGE_URL = 'https://<project_ref>.supabase.co/storage/v1'
const SERVICE_KEY = '<your-secret-key>' // Use secret key for backend operations

const storageClient = new StorageClient(STORAGE_URL, {
  apikey: SERVICE_KEY,
  Authorization: `Bearer ${SERVICE_KEY}`,
})

// Access different bucket types
const regularBucket = storageClient.from('my-bucket')
const vectorBucket = storageClient.vectors.from('embeddings-bucket')
const analyticsBucket = storageClient.analytics // Analytics API

When to use each approach:

  • Use supabase.storage when working with other Supabase features (auth, database, etc.) in frontend applications
  • Use new StorageClient() for backend applications, Edge Functions, or when you need to bypass RLS policies

Note: Refer to the Storage Access Control guide for detailed information on creating RLS policies.

Understanding Bucket Types

Supabase Storage supports three types of buckets, each optimized for different use cases:

1. Regular Storage Buckets (File Storage)

Standard buckets for storing files, images, videos, and other assets.

// Create regular storage bucket
const { data, error } = await storageClient.createBucket('my-files', {
  public: false,
})

// Upload files
await storageClient.from('my-files').upload('avatar.png', file)

Use cases: User uploads, media assets, documents, backups

2. Vector Buckets (Embeddings Storage)

Specialized buckets for storing and querying high-dimensional vector embeddings.

// Create vector bucket
await storageClient.vectors.createBucket('embeddings-prod')

// Create index and insert vectors
const bucket = storageClient.vectors.from('embeddings-prod')
await bucket.createIndex({
  indexName: 'documents',
  dimension: 1536,
  distanceMetric: 'cosine',
})

Use cases: Semantic search, AI-powered recommendations, similarity matching

See full Vector Embeddings documentation below

3. Analytics Buckets

Specialized buckets using Apache Iceberg table format, optimized for analytical queries and large-scale data processing.

// Create analytics bucket
await storageClient.analytics.createBucket('analytics-data')

// List analytics buckets
const { data, error } = await storageClient.analytics.listBuckets()

// Delete analytics bucket
await storageClient.analytics.deleteBucket('analytics-data')

Use cases: Time-series data, analytical queries, data lakes, large-scale data processing, business intelligence

See full Analytics Buckets documentation below


Handling resources

Handling Storage Buckets

  • Create a new Storage bucket:

    const { data, error } = await storageClient.createBucket(
      'test_bucket', // Bucket name (must be unique)
      { public: false } // Bucket options
    )
    
  • Retrieve the details of an existing Storage bucket:

    const { data, error } = await storageClient.getBucket('test_bucket')
    
  • Update a new Storage bucket:

    const { data, error } = await storageClient.updateBucket(
      'test_bucket', // Bucket name
      { public: false } // Bucket options
    )
    
  • Remove all objects inside a single bucket:

    const { data, error } = await storageClient.emptyBucket('test_bucket')
    
  • Delete an existing bucket (a bucket can't be deleted with existing objects inside it):

    const { data, error } = await storageClient.deleteBucket('test_bucket')
    
  • Retrieve the details of all Storage buckets within an existing project:

    // List all buckets
    const { data, error } = await storageClient.listBuckets()
    
    // List buckets with options (pagination, sorting, search)
    const { data, error } = await storageClient.listBuckets({
      limit: 10,
      offset: 0,
      sortColumn: 'created_at',
      sortOrder: 'desc',
      search: 'prod',
    })
    

Handling Files

  • Upload a file to an existing bucket:

    const fileBody = ... // load your file here
    
    const { data, error } = await storageClient.from('bucket').upload('path/to/file', fileBody)
    

    Note:
    The path in data.Key is prefixed by the bucket ID and is not the value which should be passed to the download method in order to fetch the file.
    To fetch the file via the download method, use data.path and data.bucketId as follows:

    const { data, error } = await storageClient.from('bucket').upload('/folder/file.txt', fileBody)
    // check for errors
    const { data2, error2 } = await storageClient.from(data.bucketId).download(data.path)
    

    Note: The upload method also accepts a map of optional parameters. For a complete list see the Supabase API reference.

  • Download a file from an exisiting bucket:

    const { data, error } = await storageClient.from('bucket').download('path/to/file')
    
  • List all the files within a bucket:

    const { data, error } = await storageClient.from('bucket').list('folder')
    

    Note: The list method also accepts a map of optional parameters. For a complete list see the Supabase API reference.

  • Replace an existing file at the specified path with a new one:

    const fileBody = ... // load your file here
    
    const { data, error } = await storageClient
      .from('bucket')
      .update('path/to/file', fileBody)
    

    Note: The upload method also accepts a map of optional parameters. For a complete list see the Supabase API reference.

  • Move an existing file:

    const { data, error } = await storageClient
      .from('bucket')
      .move('old/path/to/file', 'new/path/to/file')
    
  • Delete files within the same bucket:

    const { data, error } = await storageClient.from('bucket').remove(['path/to/file'])
    
  • Create signed URL to download file without requiring permissions:

    const expireIn = 60
    
    const { data, error } = await storageClient
      .from('bucket')
      .createSignedUrl('path/to/file', expireIn)
    
  • Retrieve URLs for assets in public buckets:

    const { data, error } = await storageClient.from('public-bucket').getPublicUrl('path/to/file')
    

Analytics Buckets

Supabase Storage provides specialized analytics buckets using Apache Iceberg table format, optimized for analytical workloads and large-scale data processing. These buckets are designed for data lake architectures, time-series data, and business intelligence applications.

What are Analytics Buckets?

Analytics buckets use the Apache Iceberg open table format, providing:

  • ACID transactions for data consistency
  • Schema evolution without data rewrites
  • Time travel to query historical data
  • Efficient metadata management for large datasets
  • Optimized for analytical queries rather than individual file operations

When to Use Analytics Buckets

Use analytics buckets for:

  • Time-series data (logs, metrics, events)
  • Data lake architectures
  • Business intelligence and reporting
  • Large-scale batch processing
  • Analytical workloads requiring ACID guarantees

Use regular storage buckets for:

  • User file uploads (images, documents, videos)
  • Individual file management
  • Content delivery
  • Simple object storage needs

Quick Start

You can access analytics functionality through the analytics property on your storage client:

Via Supabase Client


const supabase = createClient('https://your-project.supabase.co', 'your-publishable-key')

// Access analytics operations
const analytics = supabase.storage.analytics

// Create an analytics bucket
const { data, error } = await analytics.createBucket('analytics-data')
if (error) {
  console.error('Failed to create analytics bucket:', error.message)
} else {
  console.log('Created bucket:', data.name)
}

Via StorageClient


const storageClient = new StorageClient('https://your-project.supabase.co/storage/v1', {
  apikey: 'YOUR_API_KEY',
  Authorization: 'Bearer YOUR_TOKEN',
})

// Access analytics operations
const analytics = storageClient.analytics

// Create an analytics bucket
await analytics.createBucket('analytics-data')

API Reference

Create Analytics Bucket

Creates a new analytics bucket using Iceberg table format:

const { data, error } = await analytics.createBucket('my-analytics-bucket')

if (error) {
  console.error('Error:', error.message)
} else {
  console.log('Created bucket:', data)
}

Returns:

{
  data: {
    id: string
    type: 'ANALYTICS'
    format: string
    created_at: string
    updated_at: string
  } | null
  error: StorageError | null
}

List Analytics Buckets

Retrieves all analytics buckets in your project with optional filtering and pagination:

const { data, error } = await analytics.listBuckets({
  limit: 10,
  offset: 0,
  sortColumn: 'created_at',
  sortOrder: 'desc',
  search: 'prod',
})

if (data) {
  console.log(`Found ${data.length} analytics buckets`)
  data.forEach((bucket) => {
    console.log(`- ${bucket.id} (created: ${bucket.created_at})`)
  })
}

Parameters:

  • limit?: number - Maximum number of buckets to return
  • offset?: number - Number of buckets to skip (for pagination)
  • sortColumn?: 'id' | 'name' | 'created_at' | 'updated_at' - Column to sort by
  • sortOrder?: 'asc' | 'desc' - Sort direction
  • search?: string - Search term to filter bucket names

Returns:

{
  data: AnalyticBucket[] | null
  error: StorageError | null
}

Example with Pagination:

// Fetch first page
const firstPage = await analytics.listBuckets({
  limit: 100,
  offset: 0,
  sortColumn: 'created_at',
  sortOrder: 'desc',
})

// Fetch second page
const secondPage = await analytics.listBuckets({
  limit: 100,
  offset: 100,
  sortColumn: 'created_at',
  sortOrder: 'desc',
})

Delete Analytics Bucket

Deletes an analytics bucket. The bucket must be empty before deletion.

const { data, error } = await analytics.deleteBucket('old-analytics-bucket')

if (error) {
  console.error('Failed to delete:', error.message)
} else {
  console.log('Bucket deleted:', data.message)
}

Returns:

{
  data: { message: string } | null
  error: StorageError | null
}

Note: A bucket cannot be deleted if it contains data. You must empty the bucket first.

Get Iceberg Catalog for Advanced Operations

For advanced operations like creating tables, namespaces, and querying Iceberg metadata, use the from() method to get a configured iceberg-js client:

// Get an Iceberg REST Catalog client for your analytics bucket
const catalog = analytics.from('analytics-data')

// Create a namespace
await catalog.createNamespace({ namespace: ['default'] }, { properties: { owner: 'data-team' } })

// Create a table with schema
await catalog.createTable(
  { namespace: ['default'] },
  {
    name: 'events',
    schema: {
      type: 'struct',
      fields: [
        { id: 1, name: 'id', type: 'long', required: true },
        { id: 2, name: 'timestamp', type: 'timest