StorageStorage ServicesCapabilities

Capabilities

Adapter Capabilities

Different storage backends expose different primitives. This page enumerates which features each adapter implements natively, simulates, or rejects — so you can choose the right adapter for your use case without reading source.

Legend:

  • native — the underlying SDK / API provides this directly
  • 🟡 partial — supported with caveats (documented in the adapter's page)
  • not supported — the adapter throws METHOD_NOT_ALLOWED or STORAGE_ERROR
  • 🔁 simulated — implemented via download + reupload or similar fallback

Read & write URLs

AdaptergetReadUrl()getUploadUrl()
S3 / R2 / etc.✅ presigned GET✅ presigned PUT
S3 (light)🟡 limited (aws4fetch signing)🟡 limited (aws4fetch signing)
Azure Blob✅ SAS
GCS✅ V4 signed URL❌ (resumable URLs handled internally)
Vercel Blob✅ public URL❌ (use Vercel client tokens)
Netlify Blobs✅ signed URL
Local (disk)🟡 path-based URL
Dropbox✅ temporary link (≤ 4 h) or public shared link
Google Drive🟡 only when publicByDefault: true✅ resumable session URL
OneDrive@microsoft.graph.downloadUrl or createLinkcreateUploadSession
Box✅ shared download link
SupabasecreateSignedUrl (≤ 7 d)createSignedUploadUrl
UploadThing✅ CDN URL (public ACL) or generateSignedURL (private)
Bunny Storage🟡 via publicBaseUrl (Pull Zone)
Memory🟡 synthetic memory://${key}🟡 synthetic memory://${key}

URL options

AdapterexpiresIn capresponseContentDisposition
S3 / R2 / etc.7 d (SigV4 max)✅ forwarded as ResponseContentDisposition
Azure Blobnone (SAS)✅ via SAS query
GCS7 dresponse-content-disposition
Vercel Blobn/a (public)
Netlify Blobsvaries
Local (disk)n/a
Dropbox4 h❌ — temporary links have no override
Google Driven/a❌ — webContentLink has no override
OneDriven/a❌ — Graph download URLs have no overrides
Boxn/a❌ — shared-link URLs have no overrides
Supabase7 d🟡 mapped to Supabase download option (filename round-trips when present)
UploadThing7 d❌ — no override on UFS/CDN URLs
Bunny Storagen/a (public)❌ — no override on Storage / Pull Zone URLs
Memoryn/a

Server-side operations

Adaptercopy()move()list() prefix filter
S3 / R2 / etc.✅ CopyObject🔁 copy + deletePrefix
Azure Blob✅ Copy Blob🔁 copy + deleteprefix
GCS✅ copy🔁 copy + deleteprefix
Vercel Blob✅ copy🔁 copy + deleteprefix
Netlify Blobs🔁 copy + delete🔁 copy + deleteprefix
Local (disk)✅ fs.copyFile✅ fs.rename✅ recursive scan
Dropbox✅ filesCopyV2✅ filesMoveV2🟡 recursive listing of root
Google Drive✅ files.copy🔁 copy + delete🟡 virtual-key + appProperties
OneDrive✅ async copy✅ patch parent🟡 folder root, paginated
Box✅ copyFile✅ updateFile parent🟡 folder root, cached IDs
Supabase✅ bucket.copy✅ bucket.move❌ root only (per page limit)
UploadThing🔁 download + reupload🔁 copy + delete🟡 client-side prefix filter
Bunny Storage🔁 download + reupload🔁 copy + delete🟡 root listing, client-side
Memory✅ Map clone✅ copy + delete✅ in-memory prefix scan

Auth model

AdapterAuth shapes
S3 / R2 / etc.static / SSO / EC2 / env (AWS SDK credential chain)
Azure Blobconnection string, account key, SAS token, AAD
GCSservice-account JSON, ADC, key file, OAuth
Vercel BlobOIDC (VERCEL_OIDC_TOKEN + BLOB_STORE_ID, recommended on Vercel), BLOB_READ_WRITE_TOKEN
Netlify Blobsenv-injected on Netlify, explicit token otherwise
Local (disk)filesystem permissions
Dropboxaccess token, refresh token + app key (+ secret), pre-built Dropbox
Google Driveservice-account JSON, key file, OAuth (refresh token), JWT, env (GOOGLE_APPLICATION_CREDENTIALS)
OneDrivestatic access token, client-credentials (app-only), refresh token + redirect, pre-built Graph client
Boxdeveloper token, OAuth, CCG (enterprise / user), JWT, env
Supabaseservice-role key (env or explicit), pre-built StorageClient
UploadThingdashboard token (base64 JSON with apiKey + appId)
Bunny Storagezone + access key + region (env or explicit), pre-built StorageZone
Memorynone (in-process only)

Error normalization

All consumer adapters propagate adapter-native errors today, but the package ships wrapStorageError (in @visulima/storageutils/errors) to normalize them into a canonical UploadError with a stable ERRORS code. Wired into HTTP-fetch throws on Google Drive (resumable session) and OneDrive (copy, createUploadSession, monitor, upload-session chunks).

Mapping rule of thumb:

HTTP statusERRORS code
400BAD_REQUEST
401 / 403FORBIDDEN
404FILE_NOT_FOUND
405METHOD_NOT_ALLOWED
409FILE_CONFLICT
410GONE
413REQUEST_ENTITY_TOO_LARGE
415UNSUPPORTED_MEDIA_TYPE
422UNPROCESSABLE_ENTITY
423FILE_LOCKED
429TOO_MANY_REQUESTS
503STORAGE_BUSY
other 5xxSTORAGE_ERROR
other 4xxBAD_REQUEST

The native error is preserved on UploadError.detail for callers that need provider-specific shapes.

When in doubt

Drop down to the native client via storage.raw — every adapter exposes the underlying SDK instance there, so you can bypass the unified contract when a feature isn't in the table above.

Support

Contribute to our work and keep us going

Community is the heart of open source. The success of our packages wouldn't be possible without the incredible contributions of users, testers, and developers who collaborate with us every day.Want to get involved? Here are some tips on how you can make a meaningful impact on our open source projects.

Ready to help us out?

Be sure to check out the package's contribution guidelines first. They'll walk you through the process on how to properly submit an issue or pull request to our repositories.

Submit a pull request

Found something to improve? Fork the repo, make your changes, and open a PR. We review every contribution and provide feedback to help you get merged.

Good first issues

Simple issues suited for people new to open source development, and often a good place to start working on a package.
View good first issues