Does Fastify Work With UploadThing?
Yes, Fastify and UploadThing work together seamlessly with proper middleware configuration to handle multipart form data.
Quick Facts
How Fastify Works With UploadThing
Fastify and UploadThing integrate cleanly because UploadThing is framework-agnostic—it works through standard HTTP handlers. You set up UploadThing routes as Fastify POST handlers that receive multipart form data. Fastify's built-in multipart plugin (or `@fastify/multipart`) handles the file parsing, which UploadThing then processes. The key is registering UploadThing's `createRouteHandler` within Fastify's route definition. The developer experience is straightforward: define your file route options in UploadThing, mount it on your Fastify server, and handle uploads on the client side with UploadThing's browser SDK. Since UploadThing manages S3/cloud storage interactions server-side, Fastify mainly acts as the HTTP transport layer. This is ideal for full-stack TypeScript apps where Fastify serves your API and UploadThing handles file persistence, keeping your Fastify routes clean and focused on business logic.
Best Use Cases
Quick Setup
npm install fastify @fastify/multipart uploadthingimport Fastify from 'fastify';
import multipart from '@fastify/multipart';
import { createRouteHandler } from 'uploadthing/fastify';
import type { FileRouter } from 'uploadthing/fastify';
const fastify = Fastify();
await fastify.register(multipart);
const uploadRouter = {
imageUploader: {
middleware: async () => ({userId: 'user-123'}),
onUploadComplete: async ({file, metadata}) => {
console.log('Upload complete:', file.url);
}
}
} satisfies FileRouter;
fastify.post('/api/uploadthing',
createRouteHandler({
router: uploadRouter,
config: { isDev: true }
})
);
await fastify.listen({port: 3000});Known Issues & Gotchas
UploadThing requires environment variables (UPLOADTHING_SECRET, UPLOADTHING_APP_ID) that must be set before route registration
Fix: Load environment variables early in your Fastify startup, before calling registerRoutes(). Use dotenv or your deployment platform's secrets management.
Fastify's multipart plugin must be registered before UploadThing routes, or file parsing will fail silently
Fix: Register @fastify/multipart as the first plugin, then mount UploadThing routes after. Check plugin load order in your boot sequence.
UploadThing's error handling returns HTTP 400/500 responses, but Fastify's error serialization may format them differently than expected
Fix: Wrap UploadThing handlers in Fastify error hooks to ensure consistent error response format across your API.
Client-side UploadThing SDK expects CORS headers if frontend is on different origin
Fix: Register @fastify/cors before UploadThing routes with appropriate origin/credentials settings.
Alternatives
- •Express.js with UploadThing—more mature ecosystem, wider community support, virtually identical integration approach
- •tRPC + Fastify with multer—for full-stack TypeScript with end-to-end type safety, more granular control over file handling
- •Next.js API routes with UploadThing—opinionated framework, built-in file routing, better for full-stack monorepos
Resources
Related Compatibility Guides
Explore more compatibility guides