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 uploadthingUsage
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
| Method | Status | Notes |
|---|---|---|
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. |