Skip to content

UploadThing

File hosting with no bucket to configure — you make an app in their dashboard and get a token. The quickest of the four to get working, and the smallest free tier.

Terminal window
npx flare create shop --storage uploadthing
Terminal window
pnpm add uploadthing

The only driver with a dependency. Flare does not install it for you, because an app that picked a different driver should not carry it.

  1. Sign up at uploadthing.com with GitHub or Google. The free tier is 2 GB; no card.
  2. Create an app in the dashboard. The name is yours; it becomes part of the delivery domain.
  3. Your app → API Keys. The token is the only value Flare needs.
Flare needs Where it comes from Secret?
UPLOADTHING_TOKEN Your app → API Keys Yes

uploadthing.com/dashboard goes there.

Locally, in .env (Next.js) or .dev.vars (Cloudflare) — both git-ignored:

STORAGE_DRIVER=uploadthing
UPLOADTHING_TOKEN=…

There is no UPLOADTHING_APP_ID. The token is base64 JSON — { apiKey, appId, regions } — so the app id your files are served from is already inside it, and lib/storage/uploadthing.ts reads it from there. Flare asked for it separately until 0.13.0; the two could disagree, and when they did every upload succeeded and every read 404’d from a subdomain belonging to a different app.

For production on Vercel: Project → Settings → Environment Variables, then redeploy. On Cloudflare:

Terminal window
npx wrangler secret put UPLOADTHING_TOKEN

Files are served from <app-id>.ufs.sh, and anyone with the link can read them for as long as they exist. That is the normal way to use a CDN, and the wrong way to store a medical record. To keep reads private:

STORAGE_PUBLIC=false

Every read then goes through a signed, expiring URL your app redeems.

Worth knowing, because it explains a column you will see in their dashboard. UploadThing mints its own file key on upload, while a Flare driver is asked to store bytes under a key it was given. The two are reconciled with customId, which UploadThing accepts at upload, addresses in a delivery URL and filters by on delete.

So your key stays your key, nothing has to be stored to map between them, and the customId column in their dashboard is the path your app chose. Read it at lib/storage/uploadthing.ts.

A beginner’s guide to file uploads in Next.js covers UploadThing’s dashboard and setup in full.