S
Store

S3 Adapter

Store blobs in S3-compatible object storage with multipart uploads, presigned URLs, and R2 support.

Overview

The S3 adapter handles binary object storage. It supports AWS S3, Cloudflare R2, MinIO, and any S3-compatible service. Use it for files, images, backups, and other large binary data that does not fit well in SQLite or Postgres.

Bucket configuration

import { createStore } from "@cuitty/store/client";

const store = await createStore({
  module: "assets",
  profile: {
    id: "s3-assets",
    name: "S3 Assets",
    local: { adapter: "local.sqlite", path: ".cuitty/store/assets.sqlite" },
    remotes: [{ id: "objects", adapter: "s3.blob", bucket: "my-app-assets", secretRef: "secret://aws/s3" }],
    routes: [{ namespace: "assets", class: "blob", localAdapter: "local.cas", remoteAdapters: ["objects"] }],
    encryption: { atRest: "preferred", remote: "required", p2p: "disabled" },
    sync: { mode: "manual" },
  },
  schema: { assets: { class: "blob" } },
});

For Cloudflare R2, set the endpoint to your R2 URL:

const remote = {
  id: "objects",
  adapter: "s3.blob",
  bucket: "my-app-assets",
  endpoint: "https://<account-id>.r2.cloudflarestorage.com",
  secretRef: "secret://r2/assets",
};

Multipart uploads

Files larger than 5 MB are automatically uploaded using S3 multipart upload. Store splits the file into 8 MB parts and uploads them in parallel. If an upload is interrupted, partial parts are cleaned up automatically.

// Large file upload — multipart happens transparently
const buffer = await fs.readFile("./backup.tar.gz"); // 500 MB
await store.blob("assets").put("backups/2026-05-11.tar.gz", buffer);

You can configure the part size and concurrency:

const blob = store.blob("assets");
await blob.put("videos/intro.mp4", videoBytes, {
  contentType: "video/mp4",
});

Presigned URLs

Generate temporary URLs that grant time-limited access to a blob without exposing credentials.

const url = await store.blob("assets").signedUrl?.("reports/q1.pdf", {
  ttl: 3600, // 1 hour
  method: "GET",
});
// Share `url` with a client — no credentials needed

Supported store classes

The S3 adapter supports blobs only. For records, events, and kv, pair it with the SQLite or Postgres adapter. Store supports using multiple adapters in a single application, each backing a different store.