uploadthing
Type-safe file uploads for Next.js, React, and other web frameworks, without building your own S3 upload pipeline.
Repository Health
Technical Analysis
uploadthing is a file upload SDK that gives web apps a fully-managed storage backend and a type-safe API for defining upload routes, without provisioning storage buckets or writing presigned-URL logic by hand. On the server, createUploadthing() lets you define FileRouter endpoints with per-route file-size and count limits, middleware for auth and metadata, and typed onUploadComplete callbacks that are inferred end-to-end into your frontend components with no manual typing.
Framework adapters ship for Next.js (App Router and Pages Router), Express, Fastify, H3, and Remix, plus first-class client packages for React, Vue, Svelte, and Solid with prebuilt dropzone, button, and uploader components. The UTApi server client covers the rest of the file lifecycle — uploading from buffers or URLs, listing, renaming, deleting, generating signed URLs, and managing per-file ACLs — so teams can add production file uploads to an app in an afternoon instead of building and operating their own upload infrastructure.
What You Get
- Type-safe FileRouter - Define upload endpoints with createUploadthing() and get end-to-end type inference from server route to client hook, no manual typing required.
- Framework adapters - Drop-in route handlers for Next.js (App Router and Pages Router), Express, Fastify, H3, and Remix.
- Framework-specific client packages - @uploadthing/react, @uploadthing/vue, @uploadthing/svelte, and @uploadthing/solid ship prebuilt Dropzone, Button, and Uploader components plus headless hooks.
- Server-side UTApi client - Upload from buffers or remote URLs, list, rename, and delete files, generate signed URLs, and manage per-file ACLs from server code.
- Middleware and input validation - Attach auth/metadata middleware and validate upload input with Zod, Valibot, or any Standard Schema-compatible validator.
- Tailwind plugin - A dedicated ./tw subpath styles the prebuilt components to match your Tailwind v3 or v4 theme.
Common Use Cases
- Avatar and profile image uploads - Add a validated, size-limited image upload route to a user settings page without building server-side multipart handling.
- Document and attachment uploads in SaaS apps - Let users attach files to tickets, posts, or records with per-route file-type and size limits enforced server-side.
- Uploading from an existing URL - Migrate or mirror files from a remote URL directly into UploadThing storage server-side via uploadFilesFromUrl.
- Private file delivery with signed URLs - Serve access-controlled files, such as paid content or private documents, using generateSignedURL and ACL updates.
- Multi-framework product suites - Reuse the same server-side FileRouter definition across a Next.js web app and an Express-based internal tool.
Under The Hood
Architecture The core package/uploadthing holds a framework-agnostic route definition and adapter layer: an Effect-based builder pattern (internalCreateBuilder in src/_internal/upload-builder.ts) lets consumers chain .input().middleware().onUploadComplete() to define type-safe file routes, and makeAdapterHandler in src/_internal/handler.ts adapts that route definition to framework-specific request/response shapes for Next.js, legacy Next.js, Express, Fastify, H3, and Remix (src/next.ts, express.ts, fastify.ts, h3.ts, remix.ts). The server-side UTApi client (src/sdk/index.ts) wraps the platform HTTP client from @effect/platform with typed request and response schemas for uploading, deleting, listing, and renaming files plus ACL and signed-URL operations, while sibling packages for React, Vue, Svelte, Solid, and Nuxt provide framework-specific hooks and components on top of the same core, with shared cross-cutting logic centralized in dedicated shared and mime-types packages.
Tech Stack Written in TypeScript on top of the Effect ecosystem for structured concurrency, typed errors, and HTTP client abstraction; accepts Zod, Valibot, or any Standard Schema-compatible validator for input parsing; builds with tsdown across dual ESM/CJS output with per-adapter subpath exports; ships a dedicated Tailwind plugin supporting both major Tailwind versions; the whole repository is a pnpm and Turborepo monorepo with a Nix flake for reproducible dev environments, deployed via GitHub Actions and Changesets-driven releases.
Code Quality Extensive automated testing spans unit tests, mocked HTTP-layer tests, live integration tests gated behind a dedicated test-account secret, and compile-time type assertions exercised through the test runner’s type-testing utilities. CI enforces build, lint, format, and test on every pull request across both Node and browser environments; linting and formatting are enforced repo-wide, TypeScript strict mode is used throughout, and public APIs carry inline documentation with runnable usage examples embedded directly in source.
API Design The route-builder API is intentionally fluent and type-inferred — a chained input/middleware/onUploadComplete pipeline whose types flow automatically from the server-side route definition into client hooks with no manual annotations needed on the frontend. Framework adapters expose a consistent route-handler shape across every supported backend, minimizing what a developer must relearn when switching stacks, and dedicated forward-compatible export paths show a deliberate, incremental migration path toward newer internals without breaking existing consumers.