Better file uploadsfor developers

Developers deserve better than S3. That's why we made UploadThing, the easier (and safer) alternative. From the button to the server, we've got you covered.

Your Auth. Our Bandwidth.

The right balance of security and simplicity.

Authentication happens on your server, the upload happens on ours.

Server Code

export const fileRouter = {
  imageUploader: f({ image: { maxFileSize: "4MB" } })
    .middleware(async ({ req }) => {
      // This code runs on your server before upload
      const user = await auth(req);
      // Throw to block uploading
      if (!user)
        throw new UploadThingError("Unauthorized");
      // Return metadata to client
      return { userId: };
    .onUploadComplete(async ({ metadata, file }) => ...),
} satisfies FileRouter;

Client Code

  endpoint="imageUploader" // Typesafe btw
  onClientUploadComplete={(response) => ...}
  onUploadError={(error) => ...}

I asked for a better S3 for years. UploadThing exists because we got tired of waiting.

Theo (t3dotgg)

YouTuber, Creator of T3 Stack, CEO @ UploadThing