CodexaCodexa

Providers Reference

What each storage provider actually supports, and what its storage key looks like, once you have gone past configuration.

Storage Config covers the environment variables each provider needs to build a config. This page covers what you get once createStorageManager resolves that config into a working provider.

Capability matrix

Not every provider supports every operation. StorageManager never throws for an unsupported one, it returns undefined instead, so check for that rather than wrapping calls in try/catch.

CapabilityLocalS3CloudinaryImageKit
uploadYesYesYesYes
deleteYesYesYesYes
getSignedUrl (time-limited delivery)NoYesYesYes
getTransformedUrl (resize, crop, format)NoCDN URL only, no real transformsYesYes
getSignedUploadUrl (client-direct upload)ThrowsYes, PUTYes, POSTYes, POST

What "key" means per provider

upload always returns a key, but what it identifies is provider-specific, and delete and exists expect that exact same value back.

Providerresult.key isNotes
LocalThe relative file path under LOCAL_STORAGE_DIR
S3The relative object path (the S3 key)
CloudinaryThe asset's public_id
ImageKitThe file's fileId, returned as result.publicIdNot result.key, the one exception

Local

Reads and writes under LOCAL_STORAGE_DIR (default ./uploads) using Deno's filesystem APIs directly, so this provider only runs on Deno. Meant for local development and tests, not for a deployed app with more than one instance, since uploaded files live on that one instance's disk.

S3 and S3-compatible services

Setting S3_ENDPOINT points the same provider at any S3-compatible service, MinIO or Cloudflare R2 included, instead of AWS.

buildStorageConfig({
  STORAGE_PROVIDER: 's3',
  S3_BUCKET: env.get('S3_BUCKET')!,
  S3_REGION: env.get('S3_REGION')!,
  S3_ACCESS_KEY: env.get('S3_ACCESS_KEY')!,
  S3_SECRET_KEY: env.get('S3_SECRET_KEY')!,
  S3_ENDPOINT: 'https://<account-id>.r2.cloudflarestorage.com', // Cloudflare R2
});

getTransformedUrl on S3 only builds a CDN base URL, set via S3_CDN_BASE_URL, in front of the key. It does not perform real image transformations the way Cloudinary and ImageKit do.

Cloudinary and ImageKit

Both are full image and video CDNs with real on-the-fly transformations, resize, crop, format conversion, applied through the URL itself.

storage.getTransformedUrl(result.key, {
  width: 200,
  height: 200,
  crop: 'fill',
  format: 'webp',
});

Transformation options

The same shape getTransformedUrl and upload's eagerTransformations both accept.

Prop

Type

On this page