FluxMedia
Copy page
Open in ChatGPTOpen in Claude

AWS S3 Provider

Simple, reliable file storage with the AWS ecosystem.

Installation

pnpm add @fluxmedia/core @fluxmedia/s3 @aws-sdk/client-s3 @aws-sdk/lib-storage

Configuration

import { MediaUploader } from '@fluxmedia/core';
import { S3Provider } from '@fluxmedia/s3';

const uploader = new MediaUploader(
  new S3Provider({
    region: 'us-east-1',
    bucket: 'my-media-bucket',
    accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
  })
);

Configuration Options

Option Type Required Description
region string Yes AWS region (e.g., 'us-east-1')
bucket string Yes S3 bucket name
accessKeyId string Yes AWS access key
secretAccessKey string Yes AWS secret key
endpoint string No Custom endpoint (for S3-compatible services)
forcePathStyle boolean No Force path style URLs

Basic Usage

const result = await uploader.upload(file, {
  folder: 'uploads',
  filename: 'my-file.jpg',
});

console.log(result.url);
// https://my-media-bucket.s3.us-east-1.amazonaws.com/uploads/my-file.jpg
console.log(result.storageKey); // uploads/my-file.jpg

Upload with Progress

const result = await uploader.upload(file, {
  folder: 'uploads',
  onProgress: (percent) => {
    console.log(`Upload progress: ${percent}%`);
  },
  onByteProgress: (loaded, total) => {
    console.log(`${loaded}/${total} bytes`);
  },
});

Batch Uploads

Upload multiple files with concurrency control:

const results = await uploader.uploadMultiple(files, {
  folder: 'batch-uploads',
  concurrency: 5,
  onBatchProgress: (completed, total) => {
    console.log(`Uploaded ${completed}/${total} files`);
  },
});

S3-Compatible Services

Works with DigitalOcean Spaces, MinIO, and other S3-compatible services:

// DigitalOcean Spaces
const uploader = new MediaUploader(
  new S3Provider({
    region: 'nyc3',
    bucket: 'my-space',
    accessKeyId: 'your-spaces-key',
    secretAccessKey: 'your-spaces-secret',
    endpoint: 'https://nyc3.digitaloceanspaces.com',
    forcePathStyle: false,
  })
);

// MinIO
const uploader = new MediaUploader(
  new S3Provider({
    region: 'us-east-1',
    bucket: 'my-bucket',
    accessKeyId: 'minio-access-key',
    secretAccessKey: 'minio-secret-key',
    endpoint: 'http://localhost:9000',
    forcePathStyle: true,
  })
);

Supported Features

S3 is storage-only (no transformations):

uploader.supports('transformations.resize'); // false
uploader.supports('capabilities.signedUploads'); // true
uploader.supports('capabilities.multipartUpload'); // true

Native SDK Access

Access the underlying AWS S3 client for advanced operations:

const s3Client = uploader.provider.native;

const { ListBucketsCommand } = await import('@aws-sdk/client-s3');
const buckets = await s3Client.send(new ListBucketsCommand({}));

Environment Variables

AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_REGION=us-east-1
S3_BUCKET=my-bucket

Adding Transformations

Use CloudFront + Lambda@Edge for image transformations, or consider Cloudinary for built-in support.