UploadThing

UploadThing via the uploadthing/server SDK. Auto-loads UPLOADTHING_TOKEN and maps your keys onto UploadThing's customId so operations route by your key.

Installation

uploadthing is an optional peer dependency of files-sdk - install alongside the SDK so the adapter's imports resolve at runtime.

npm install files-sdk uploadthing

Usage

UploadThing via the official uploadthing/server SDK. UploadThing generates its own internal file keys, so the adapter maps the user-supplied key onto UploadThing's customId with defaultKeyType: "customId" - every subsequent operation routes by your key, not the auto-generated one.

import { Files } from "files-sdk";
import { uploadthing } from "files-sdk/uploadthing";

// UPLOADTHING_TOKEN is auto-loaded from env. The token is a base64
// JSON of { apiKey, appId, regions[] } - the adapter decodes it at
// construction so url() can synthesize the public CDN URL and
// signedUploadUrl() can sign a UFS PUT URL without an API round trip.
const files = new Files({
  adapter: uploadthing({
    // acl: "public-read",       // default; switch to "private" to mint
    //                            // signed URLs through generateSignedURL
    // slug: "mediaUploader",    // required only for signedUploadUrl()
  }),
});

Options

Prop

Type

Compatibility

MethodStatusNotes
upload⚠️User metadata and cacheControl aren't supported by the UFS API, so passing either throws rather than silently dropping it. Resumable uploads (control) are not supported — UploadThing manages chunking server-side and exposes no resumable session.
download
delete
list⚠️UploadThing's listFiles is offset/limit, not cursor-based - the adapter encodes the next offset as a numeric cursor. prefix is unsupported server-side; the adapter filters the returned page client-side, which under-returns when the prefix isn't satisfied within a single page.
search⚠️Built on listAll — inherits this adapter's list behavior above. Client-side key match (glob, regex, substring, exact).
head⚠️UploadThing has no metadata endpoint, so head() issues a HEAD request against the resolved file URL (signed for private, CDN for public) and parses size/content-type/etag/last-modified from the response headers. User metadata isn't supported.
exists⚠️UploadThing has no metadata endpoint, so exists() issues a HEAD request against the resolved file URL (signed for private, CDN for public) and treats 404 as false.
copy⚠️Read-then-write - UploadThing has no server-side copy primitive, so the source is downloaded and re-uploaded. Costs an egress + an ingest; not atomic.
url⚠️Public adapters return the permanent CDN URL https://{appId}.ufs.sh/f/{key} and silently ignore expiresIn. Private adapters mint a signed read URL via generateSignedURL (1-hour default). responseContentDisposition throws either way - UploadThing has no Content-Disposition override on signed or CDN URLs. Use a private adapter for buckets with untrusted user-uploaded content.
signedUploadUrl⚠️PUT URL only - built against UploadThing's UFS ingest endpoint with an HMAC-SHA256 signature over the URL. maxSize is advisory: UploadThing enforces upload caps via the file-router config tied to the adapter's slug, not via the URL signature. minSize is ignored (no equivalent on UFS). The user-supplied key is bound as x-ut-custom-id so subsequent ops can route by it.

On this page