Quick Start

Configure scopes, upload your first file, and return a public URL using @igniter-js/storage.

Build Your First Upload Path

Follow these steps to configure a manager, add scopes, and serve a public URL in minutes.

Create the storage instance

import { IgniterStorage } from '@igniter-js/storage'

export const storage = IgniterStorage.create()
  .withAdapter('s3', { bucket: 'my-bucket', region: 'us-east-1' })
  .withUrl('https://cdn.myapp.com')
  .addScope('public', '/public')
  .addScope('user', '/users/[identifier]')
  .build()

The builder merges .withAdapter() and .withUrl() with environment defaults. Scopes become typed: storage.scope('user', '123').upload(...) requires the identifier because the path template includes [identifier].

Upload to a scope

const avatar = new Blob(['image-bytes'], { type: 'image/png' })

const file = await storage
  .scope('user', '123')
  .upload(avatar, 'avatar.png')

console.log(file.url) // https://cdn.myapp.com/users/123/avatar.png

The manager infers content type from the filename and sets public caching (cache-control: public, max-age=31536000).

Fetch or clean up

const metadata = await storage.get(file.url) // works with URL or relative path
const listed = await storage.scope('user', '123').list()
await storage.delete(file.path)

Use list for inventories and delete for cleanups. If you need to reorganize files, use copy or move (adapter support required).

Handle Errors Early

Wrap uploads with typed errors to present helpful messages:

import { IgniterStorageError } from "@igniter-js/storage";

try {
  await storage.upload(file, "public/banner.pdf");
} catch (error) {
  if (IgniterStorageError.is(error)) {
    // Guardrails
    if (error.code === "IGNITER_STORAGE_UPLOAD_POLICY_VIOLATION") {
      return response.badRequest({
        message: "File does not meet requirements",
      });
    }

    return response.error({ message: error.message });
  }

  throw error;
}

Next Steps

Design your hierarchy in Scopes & Paths, set size/type guardrails in Policies & Validation, and add lifecycle hooks in Hooks & Telemetry.