Introduction
Full-stack S3 toolkit for the React ecosystem — server handlers, client hooks, shadcn UI, and database tracking.
dimah-s3 is a modular, full-stack S3 toolkit for React and Node.js runtimes. It provides typed server handlers, headless React hooks, optional shadcn UI components, and a database plugin for object tracking when your application needs it.
2.0 beta
This site documents the 2.0 beta. Install with the beta dist-tag. A new beta
ships every few days and can include breaking changes until 2.0.0. Stable 1.x
stays at s3.dimah.dev. Moving a 1.7 app: Upgrade
to 2.0 beta.
Architecture flow
- Browserrequests signed URL
- Serverexecutes guards and signs URL
- S3 Bucketreceives the upload
The backend signs a short-lived URL, the browser talks to your bucket, and AWS credentials never leave the server. Downloads can also pass through your server as a proxy.
For coding agents — llms.txt · llms-full.txt.
What you get
- Fast setup — a working upload in minutes
- Full stack — server, client, and optional shadcn UI
- Full lifecycle — upload, download, and delete, including multipart
- Server hooks — auth, quotas, confirm, and cleanup on the server (Better Auth-like)
- Optional database — ownership and listings when you need them
It is not an S3 SDK wrapper. List, copy, tagging, and other operations stay in your own code with the AWS SDK.
Frequently asked questions
When you own the S3-compatible bucket and need more than an upload picker: server-owned keys, verified confirmation, private downloads, guarded deletion, multipart resume, or optional database tracking.
If you are choosing between managed storage, an upload-focused toolkit, or a client uploader, use the comparison guide.
No. dimah-s3 covers presign upload, download, and delete. Use the AWS SDK for everything else — list, copy, retention, tagging, and similar work.
Yes. Configure an AWS SDK S3Client for the provider. Uploads use presigned
PUT by default, which R2 supports; MinIO commonly needs forcePathStyle: true.
See the provider guides for endpoints and CORS.
The browser sends a route name. The server runs guards, chooses a key inside that route's namespace, and returns a short-lived signed request with a signed upload ticket. Confirm accepts only uploads the server started, and credentials never leave the server.
Yes. The server picks the part layout, and the client uploads parts in
parallel with retries, cancellation, and per-part SHA-256 checks when the
route asks for them. Add a persistent UploadStore; after a reload, the user
reselects the same local file and the client resumes. See
Upload Store.
Explore documentation
Quickstart
Get a working upload running in a few minutes.
Server Guide
Configure routes, lifecycle hooks, guards, and runtimes.
React Client
Headless hooks for upload, download, and delete.
UI Components
Composable shadcn controls for upload, download, and delete.
Providers
Setup guides for AWS S3, Cloudflare R2, and MinIO.
Database Plugin
Track files, ownership, and listings.
Comparison
Compare dimah-s3 with Better Upload, UploadThing, and Uppy.
Upgrade to 2.0 beta
Move a 1.7 app onto the 2.0 beta. Betas can break until 2.0.0.