Open-source project
pingdotgg/uploadthing avatar
pingdotgg/uploadthing

UploadThing: file uploads for Next.js, React and Svelte apps

File uploads for modern web devs

5,332 stars448 forksTypeScriptMIT

At a glance

What is it?
UploadThing is a TypeScript file-upload toolkit whose server routes declare what can be uploaded and whose React, Solid, Svelte and Vue packages handle the client side. It is a hosted service with an MIT-licensed SDK, and the SDK is the only part this repository covers.
Who is it for?
Adopt UploadThing when you want upload routes defined in TypeScript next to the rest of your backend and you accept that the storage layer is a hosted service rather than an S3 bucket you own. Do not adopt it if your files must stay inside your own cloud account, or if your framework is not among the examples in the repository.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem UploadThing solves for web developers

Uploading a file from a browser is a series of small chores. You need a place to put the bytes, a signed URL or a proxy route so the browser does not need your storage credentials, a size and type check on the server, progress reporting on the client, and some way to know when the upload finished so you can attach the resulting file to a database row. Every framework has a slightly different way of expressing those pieces, and most teams end up writing the same middleware twice.

UploadThing's answer is to let you declare an upload route in TypeScript and let the SDK generate the client-side hook for it. The README describes the repository as containing "the packages, docs and examples for uploadthing", with a framework-agnostic core package plus React, Solid, Svelte and Vue bindings. The audience is web developers working in TypeScript who want the upload endpoint to live in the same codebase as the rest of their server logic, rather than in a separate dashboard or a hand-written S3 presign route.

It is worth being precise about what is open here. The licence file in the repository is MIT, and that covers the SDK packages. The storage service the SDK talks to is a hosted product at uploadthing.com. The README's contributing note makes the split explicit: "If your change also requires infrastructure changes, please reach out and we can work together to make the necessary changes on our end." Self-hosting the storage layer is not part of this repository.

How the file router and the client hooks fit together

The architecture has two halves that meet at a generated type. On the server you build a file router, a map of route names to handlers, and each handler declares constraints such as the maximum file size and the accepted types. That router is exported from a route file in your framework's server directory. On the client, a generator reads the router's type and produces typed components and hooks, so the component for a given route name already knows the constraints and the shape of the result.

The repository layout reflects that split. There is packages/uploadthing for the framework-agnostic server and client code, packages/react for the React components and hooks, and packages/solid for the Solid equivalents. The examples directory shows the same pattern repeated across environments: minimal-appdir and minimal-pagedir for Next.js, minimal-sveltekit, minimal-nuxt, minimal-astro-react, minimal-solidstart, minimal-tanstack-start, minimal-expo, and a set of integrations such as with-clerk-appdir, with-drizzle-appdir, with-serveractions, with-react-image-crop and with-tailwindcss. The breadth of examples is the strongest signal in the repository about what the project is actually used for: form attachments, profile pictures, and database-backed file records.

The trade-off in this design is that the router is the source of truth. Anything the client needs to know about an upload has to be expressible in the handler's declaration, and the generated client types follow from it. That is convenient when your upload rules are static, and awkward when they depend on runtime state that the type generator cannot see.

Installing UploadThing and defining a first upload route

The README does not include install instructions, but the repository structure does: packages/uploadthing holds the framework-agnostic package and packages/react holds the React bindings, so those are the two names to install. The package.json at the repository root pins Node to >=22.x and pnpm to 10.x for working on the monorepo itself, which is a separate concern from consuming the published packages.

bash
pnpm install

That is the install step the README gives for the repository itself, under its contributing instructions. To use the packages in your own app, the directory names packages/uploadthing and packages/react are the two you need, and the examples/minimal-appdir directory is the smallest working Next.js app-directory setup to copy from.

Once the packages are in place, the pattern the examples follow is a route name, a middleware chain, and an uploader that states the allowed types and size. The router is exported from a server route file, and its type is what the client generator consumes.

The repository's own build and test commands are driven through turbo, and the root package.json lists filtered variants such as build:react and build:vanilla alongside test:all and typecheck. If you are working inside the monorepo rather than consuming the published packages, those are the scripts to run.

What you should see after wiring both ends is an upload that reports progress in the browser and, on completion, a callback on the server carrying the file's URL and whatever the middleware returned. The README points to examples/minimal-appdir as the smallest working Next.js app-directory version, and that is the right file to open when the generated types do not line up.

Where UploadThing stops being the right tool

The clearest limitation is the one the licence does not address. The SDK is MIT, but the storage, the dashboard and the upload endpoints are run by the project's maintainers. If your requirements say files must live in a bucket inside your own cloud account, or that no file data may leave your infrastructure, UploadThing is the wrong shape regardless of how good the SDK is. The repository contains no self-hosting path for the storage side, and the contributing note treats infrastructure changes as something the maintainers handle on their end.

A second boundary is framework coverage. The examples cover Next.js in both router modes, SvelteKit, Nuxt, Astro with React, SolidStart, TanStack Start and Expo, plus a backend-adapters example. That is a wide set, but it is a list of examples, not a compatibility guarantee. The README's own table of contents only promotes the Next.js app directory, Next.js pages directory and SolidStart examples alongside the React and Solid packages. If your framework is not in that list, the honest answer is that you would be adapting the framework-agnostic package yourself.

There is also a maintenance question that the repository facts answer more precisely than any adjective. The last push to the default branch was on 2026-08-17, and the most recent releases listed are [email protected], @uploadthing/[email protected] and @uploadthing/[email protected], all dated 2025-08-17. The repository is not archived. Note the gap between the release dates and the last push: work on the repository has continued after the last tagged release, so a reader checking only npm versions would underestimate how much has changed on main.

UploadThing compared with S3, Cloudflare R2 and Cloudinary

The comparison people search for is UploadThing against S3, Cloudflare R2 and Cloudinary, and the difference is mostly about who owns the storage layer and how much of the upload flow is generated for you.

With S3 or Cloudflare R2, you own the bucket and pay the provider directly. The SDK does not exist because there is nothing to abstract: you write a presign endpoint, hand the URL to the browser, and handle the completion callback yourself. You get full control over regions, lifecycle rules and access policies, and you take on the code that UploadThing generates. R2 is the closer of the two to UploadThing in spirit, since it is object storage with S3-compatible semantics and no egress fees, but it is still a bucket you configure rather than an upload route you declare.

Cloudinary sits on the other side. It is a hosted media platform whose value is in transformations, responsive delivery and image processing rather than in the upload handshake. If your problem is resizing and serving images at different breakpoints, Cloudinary addresses more of it than UploadThing does. If your problem is getting an arbitrary file from a browser into storage with typed constraints and a completion callback, UploadThing is the narrower and more direct fit.

The honest summary is that UploadThing is not a storage provider you can migrate away from by changing a connection string. Choosing it means accepting a hosted dependency in exchange for less upload plumbing in your TypeScript codebase.

Maintenance, versions and what the MIT licence does not cover

The repository is a pnpm and Turborepo monorepo. The root package.json requires Node >=22.x and pnpm 10.x, pins packageManager to [email protected], and drives builds and tests through turbo scripts such as build:all, test:all and typecheck, with filtered variants like build:react and build:vanilla. Contributions go through a changeset: the README's steps are to fork and clone, install with pnpm install, make the change, run pnpm changeset, and open a pull request with the changeset included. That is a conventional setup, and it means version bumps are tied to explicit changeset entries rather than to commits on main.

The packages are versioned independently, which is visible in the release list: [email protected] alongside @uploadthing/[email protected] and @uploadthing/[email protected]. If you depend on more than one of them, expect to track two version lines rather than one, and read the changeset for each before upgrading.

On licensing: the repository is MIT, which is permissive for the SDK code. That licence says nothing about the hosted service, its terms, or its pricing. The README links to uploadthing.com and docs.uploadthing.com, and those are the pages that govern the service side. This is not legal advice, and the distinction between the code licence and the service terms is the thing to check with whoever handles procurement on your team.

Editorial conclusion

Adopt UploadThing when you want upload routes defined in TypeScript next to the rest of your backend and you accept that the storage layer is a hosted service rather than an S3 bucket you own. Do not adopt it if your files must stay inside your own cloud account, or if your framework is not among the examples in the repository. Before committing, verify the token and callback configuration for your framework, confirm how the client components are wired into your router, and read the current pricing and terms on uploadthing.com, since the SDK licence says nothing about the service it talks to.

Frequently asked questions

How do you use UploadThing in a Next.js app?

You define a file router in a server route, export its type, and pass that type to the client generator to get typed upload components. The repository includes examples/minimal-appdir and examples/minimal-pagedir as the smallest working Next.js versions of that setup.

What is UploadThing and what does it do?

It is a file-upload toolkit for TypeScript web apps. The README describes the repository as containing the packages, docs and examples for uploadthing, with a framework-agnostic core plus React, Solid, Svelte and Vue bindings.

Is UploadThing open source?

The SDK packages in the repository are MIT licensed. The storage service they talk to is hosted at uploadthing.com, and the README's contributing note treats infrastructure changes as something the maintainers handle rather than something the repository provides.

Is UploadThing free?

The repository does not state pricing. The MIT licence covers the SDK code, and the README links to uploadthing.com for the service itself, which is where any pricing or free-tier terms would be defined.

How does UploadThing compare with S3 or Cloudflare R2?

S3 and R2 are object storage you configure and pay for directly, so you write the presign endpoint and completion handling yourself. UploadThing generates the typed upload route and client components, but the storage layer is a hosted service rather than a bucket in your account.

Official sources

  1. License: MIT
  2. pingdotgg/uploadthing on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/pingdotgg-uploadthing.svg)](https://hysenlabs.com/projects/pingdotgg-uploadthing)