---
title: "Build the package"
description: "<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"
type: skill
canonical_url: https://claudary.paisolsolutions.com/skills/readme-240
source: "Claudary"
difficulty: intermediate
author: "Claude Code Knowledge Pack"
date: 2026-07-10T11:36:17.185Z
license: CC-BY-4.0
attribution: "Build the package — Claudary (https://claudary.paisolsolutions.com/skills/readme-240)"
---

# 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

## 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](https://github.com/supabase/supabase-js/workflows/CI/badge.svg)](https://github.com/supabase/supabase-js/actions?query=branch%3Amaster)
[![Package](https://img.shields.io/npm/v/@supabase/storage-js)](https://www.npmjs.com/package/@supabase/storage-js)
[![License: MIT](https://img.shields.io/npm/l/@supabase/supabase-js)](#license)
[![pkg.pr.new](https://pkg.pr.new/badge/supabase/storage-js)](https://pkg.pr.new/~/supabase/storage-js)

</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](https://github.com/orgs/supabase/discussions/37217), 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

```bash
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:

```js
import { createClient } from '@supabase/supabase-js'

// 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:

```js
import { StorageClient } from '@supabase/storage-js'

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](https://supabase.com/docs/guides/storage/access-control) 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.

```js
// 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.

```js
// 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](#vector-embeddings)**

#### 3. Analytics Buckets

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

```js
// 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](#analytics-buckets)**

---

### Handling resources

#### Handling Storage Buckets

- Create a new Storage bucket:

  ```js
  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:

  ```js
  const { data, error } = await storageClient.getBucket('test_bucket')
  ```

- Update a new Storage bucket:

  ```js
  const { data, error } = await storageClient.updateBucket(
    'test_bucket', // Bucket name
    { public: false } // Bucket options
  )
  ```

- Remove all objects inside a single bucket:

  ```js
  const { data, error } = await storageClient.emptyBucket('test_bucket')
  ```

- Delete an existing bucket (a bucket can't be deleted with existing objects inside it):

  ```js
  const { data, error } = await storageClient.deleteBucket('test_bucket')
  ```

- Retrieve the details of all Storage buckets within an existing project:

  ```js
  // 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:

  ```js
  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:
  >
  > ```javascript
  > 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](https://supabase.com/docs/reference/javascript/storage-from-upload).

- Download a file from an exisiting bucket:

  ```js
  const { data, error } = await storageClient.from('bucket').download('path/to/file')
  ```

- List all the files within a bucket:

  ```js
  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](https://supabase.com/docs/reference/javascript/storage-from-list).

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

  ```js
  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](https://supabase.com/docs/reference/javascript/storage-from-upload).

- Move an existing file:

  ```js
  const { data, error } = await storageClient
    .from('bucket')
    .move('old/path/to/file', 'new/path/to/file')
  ```

- Delete files within the same bucket:

  ```js
  const { data, error } = await storageClient.from('bucket').remove(['path/to/file'])
  ```

- Create signed URL to download file without requiring permissions:

  ```js
  const expireIn = 60

  const { data, error } = await storageClient
    .from('bucket')
    .createSignedUrl('path/to/file', expireIn)
  ```

- Retrieve URLs for assets in public buckets:

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

```typescript
import { createClient } from '@supabase/supabase-js'

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

```typescript
import { StorageClient } from '@supabase/storage-js'

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:

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

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

**Returns:**

```typescript
{
  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:

```typescript
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:**

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

**Example with Pagination:**

```typescript
// 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.

```typescript
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:**

```typescript
{
  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](https://github.com/supabase/iceberg-js) client:

```typescript
// 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

---

Source: [Claudary](https://claudary.paisolsolutions.com/skills/readme-240) · https://claudary.paisolsolutions.com
