Krantho is in active development and not yet published to npm. Read what that means today.
esc

Search the documentation and product pages. Type “theme” to switch themes.

@krantho/media-s3

The media file store on S3-compatible object storage, such as AWS S3, Cloudflare R2 and MinIO.

Intermediate

The media file store for media.provider: 's3'. It writes each uploaded file to an S3-compatible bucket with Cache-Control: public, max-age=31536000, immutable, using @aws-sdk/client-s3.

Install#

pnpm add @krantho/media-s3

Configure#

SettingVariableDefault
media.s3.bucketKRANTHO_MEDIA_S3_BUCKETunset, required
media.s3.regionKRANTHO_MEDIA_S3_REGIONunset, required (auto for R2)
media.s3.endpointKRANTHO_MEDIA_S3_ENDPOINTunset (AWS)
media.s3.forcePathStyleKRANTHO_MEDIA_S3_FORCE_PATH_STYLEfalse
media.s3.publicUrlKRANTHO_MEDIA_S3_PUBLIC_URLhttps://<bucket>.s3.<region>.amazonaws.com without an endpoint; required with one
media.s3.accessKeyIdKRANTHO_MEDIA_S3_ACCESS_KEY_IDunset (default chain)
media.s3.secretAccessKeyKRANTHO_MEDIA_S3_SECRET_ACCESS_KEY (secret)unset (default chain)
.env
# AWS S3: credentials from the instance or task role
KRANTHO_MEDIA_PROVIDER=s3
KRANTHO_MEDIA_S3_BUCKET=my-site-media
KRANTHO_MEDIA_S3_REGION=eu-north-1

Cloudflare R2 uses region=auto, the account endpoint and the bucket's public domain as publicUrl; MinIO also needs forcePathStyle=true. Media shows both.

Credentials#

Set both keys or neither. Without them, the AWS SDK's default credential chain applies: environment variables, shared config files, the ECS task role, web identity, EC2 instance metadata. The credentials need s3:PutObject, s3:GetObject and s3:DeleteObject on the bucket's objects.

Public read#

A file's URL is <publicUrl>/<key>, and it must be readable there: a bucket policy granting s3:GetObject, public access on R2 or MinIO, or a CDN in front of the bucket with publicUrl set to it. Private buckets and signed URLs are not supported.

How it is verified#

krantho's tests check the requests the store sends through a mocked S3 client: keys, content types, Cache-Control, copies and the URLs it returns. They do not run against a live AWS, R2 or MinIO bucket. Before relying on it in production, upload, replace and delete one image on a staging bucket and open its URL.

Next steps#

  • The other stores and image URLs: Media