s3://dator.dev/bouquet/ macOS 14 or later

Bouquet

A native S3 client for the Mac.

Browse buckets the way you browse folders. Move, search, share, edit, sync, and configure S3 from one window, so the AWS Console and the command line can stay closed.

Coming to the Mac App Store

A line drawing of the Bouquet icon: a bucket holding daisies, a poppy, lavender, and billy buttons
The Bouquet main window: a sidebar of buckets, a folder listing with logo.svg selected, a finished download in the Transfers popover, and the inspector showing the object's size, key, and editable metadata
A bucket open in Bouquet, with the inspector showing an object's metadata.

What it does

Browse
Buckets and folders in a Finder-style window, with Quick Look, image thumbnails, favorites, and as many windows and tabs as you need.
Search
Filter the current folder as you type, or search everything under a prefix.
Transfer
Drag folders in and out of Finder. Uploads and downloads are recursive, show real progress, retry on failure, and ask before overwriting: replace, skip, or keep both.
Edit
Change text objects and metadata such as Content-Type and Cache-Control in place, without downloading first.
Share
Copy a presigned link that expires in an hour, a day, or a week. Plain HTTPS URLs and S3 URIs are one menu item away.
Restore
Browse an object's versions and delete markers. Download or restore any of them. Permanent deletion is always explicit.
Sync
Keep a local folder and an S3 prefix in two-way sync.
Automate
Hooks run after objects change: a shell command, an HTTP request, or a CloudFront invalidation.
Configure
Bucket policies, IAM, lifecycle rules, and CloudFront, edited in the app. Grant access to a single folder without leaving it.

Only S3, on purpose

Most file-transfer apps speak every protocol and know each one a little. Bouquet speaks S3 only, so it can go all the way down.

Credentials come from your existing ~/.aws profiles, SSO included, or are stored in macOS Keychain when you add a connection in the app. Every request is signed in the app and sent straight to the service. There is no server in between.

Works with

ServiceEndpoint
Amazon S3Any region, any profile
Fastly Object Storagehttps://<region>.object.fastlystorage.app
Cloudflare R2https://<account-id>.r2.cloudflarestorage.com
MinIOhttp://localhost:9000
Backblaze B2https://s3.<region>.backblazeb2.com
DigitalOcean Spaceshttps://<region>.digitaloceanspaces.com

Anything else that speaks the S3 API works too. Add a connection with its endpoint, region, and keys.

Hooks

A hook runs after objects in a bucket or folder change. A shell hook gets every changed key on standard input, one per line, with the connection's credentials in the environment. This one purges the changed paths from CloudFront:

sed 's#^#/#' | xargs aws cloudfront create-invalidation \
  --distribution-id E123ABC --paths

HTTP hooks cover webhooks and CDN purges with no shell at all, and CloudFront invalidation is built in as its own kind. Hooks never block or roll back the S3 operation.