Providers
Providers
Configure AWS S3, Cloudflare R2, MinIO, and other S3-compatible storage.
dimah-s3 talks to storage through the AWS SDK S3Client. Any service that speaks enough of the S3 API can work — Amazon S3, Cloudflare R2, MinIO, and similar backends.
“S3-compatible” is not the same as Amazon S3. Providers skip or ignore parts of the API. With a presign-first stack, those gaps show up fast:
| Topic | Why it matters |
|---|---|
| Presigned POST vs PUT | Default upload is POST. Some providers only accept PUT. |
| Object ACL | acl: "public-read" needs real ACL support. Others use bucket policies or a public-access toggle. |
| Endpoint & addressing | Custom endpoints often need endpoint and sometimes forcePathStyle: true. |
| CORS | Browser uploads hit storage directly — the bucket must allow your origin, methods, and headers. |
| Public URLs | Public reads may use a CDN, custom domain, or *.r2.dev — not object ACL. |
Wire the shared client once in Quickstart. Use the guides below only for the provider-specific extras that defaults do not cover.
Comparison
| AWS S3 | Cloudflare R2 | MinIO | |
|---|---|---|---|
| Presigned POST | ✅ | ❌ | ✅ |
| Presigned PUT | ✅ | ✅ (required) | ✅ |
| Object ACL | ✅ | ❌ (ignored) | ❌ (use policies) |
resolveObjectAcl | ✅ | ❌ | ❌ |
Custom endpoint | Optional | Required | Required |
forcePathStyle | Usually off | Off | On |
Configuration
export const s3 = dimahS3({
s3: s3Client,
defaultBucket,
// Default is "POST". Use "PUT" when the provider has no Presigned POST (e.g. R2).
upload: { enabled: true, method: "PUT" },
// Extra GetObjectAcl round-trip — leave false unless the provider supports ACL.
resolveObjectAcl: false,
});Client hooks and @dimah-s3/ui read method: "PUT" | "POST" from the presign response — change this on the server only.