Blog
Jul 18, 2026 - 4 MIN READ
Comprehensive Guide to Using Uploadthing with Express and Typescript

Comprehensive Guide to Using Uploadthing with Express and Typescript

This note provides a detailed exploration of setting up file uploads using Uploadthing in an Express.js application with TypeScript, focusing on security best practices and the potential use of signed URLs.

Sachin Thapa

Sachin Thapa

This note provides a detailed exploration of setting up file uploads using Uploadthing in an Express.js application with Typescript, focusing on security best practices and the potential use of signed URLs. The information is derived from analyzing Uploadthing's documentation, ensuring a thorough understanding for developers seeking to implement this service.

Overview of Uploadthing

Uploadthing is a file upload solution designed for modern web developers, particularly those using full-stack TypeScript applications. It supports various frameworks like Next.js, Astro, Solid Start, SvelteKit, and Nuxt, with backend adapters including Express, Fastify, H3, and WinterCG/Fetch API, and frontend libraries such as React, Vue, SolidJS, Svelte, and Vanilla JS. This versatility makes it suitable for diverse project needs, especially in Express environments with Typescript.

Step-by-Step Setup Process

To integrate Uploadthing with Express and Typescript, follow these detailed steps:

  1. Package Installation:
    • Begin by installing the Uploadthing package using the command npm install uploadthing. This installs the necessary dependencies for both server and client-side operations.
  2. Environment Configuration:
    • Access the Uploadthing dashboard to create a new application and retrieve an API key from the API Keys tab. Set this key as an environment variable in your project, typically as UPLOADTHING_TOKEN=your_token. This ensures secure interaction with the Uploadthing SDK.
  3. File Router Creation:
    • Create a file, such as src/uploadthing.ts, to define your file routes using the createUploadthing function from "uploadthing/express". For example, to set up an image uploader:
      import { createUploadthing } from "uploadthing/express";
      
      const f = createUploadthing();
      
      const imageUploader = f({ "image": { maxFileSize: "4MB", maxFileCount: 1, acl: "private" } })
        .middleware(async ({ req }) => {
          // Security check: Ensure user is authenticated
          if (!req.user) {
            throw new Error("Unauthorized");
          }
        })
        .onUploadComplete(({ file }) => {
          // Post-upload actions: Log or store the file URL
          console.log(file.url);
        });
      
      export const uploadRouter = f({
        imageUploader,
      });
      
    • The middleware function allows for authorization checks, such as verifying user login status, while onUploadComplete handles post-upload tasks, providing access to file properties like the URL.
  4. Server Integration:
    • In your main server file, typically src/index.ts, integrate the file router with Express using the createRouteHandler from "uploadthing/express". Mount it at a specific endpoint, such as /api/uploadthing:
      import express from "express";
      import { createRouteHandler } from "uploadthing/express";
      import { uploadRouter } from "./uploadthing";
      
      const app = express();
      
      // Mount the Uploadthing route
      app.use("/api/uploadthing", createRouteHandler({
        router: uploadRouter,
      }));
      
      // Start the server
      app.listen(3000, () => {
        console.log("Server started on port 3000");
      });
      
    • This setup ensures that file upload requests are handled through the defined endpoint.
  5. Client-Side Implementation:
    • On the client side, utilize the @uploadthing/react package to generate upload components, such as an upload button. Configure it with the server's endpoint, for example, https://your-server.com/api/uploadthing. This allows users to initiate uploads seamlessly within your application.

Security Best Practices

Security is paramount when handling file uploads. Uploadthing provides several mechanisms to ensure secure operations:

  • Middleware for Authentication: Implement middleware within the file router to authorize users before uploads. For instance, check if a user is logged in using a service like Clerk, throwing an error if unauthorized:
    • Example: throw new Error("You must be logged in to upload a profile picture") if no user is signed in.
  • Access Control Lists (ACL): Since version 6.0, Uploadthing allows setting the acl property in route configurations to "public-read" or "private". Setting it to "private" restricts access, ensuring only authorized users can view or download files. This is crucial for protecting sensitive data.

Handling File Access and Signed URLs

Accessing uploaded files is facilitated through the onUploadComplete callback, which provides a file object containing properties like the URL. For example:

  • The file.url can be used to access the uploaded file, which is particularly useful for storing in a database or sharing within the application.

However, for files with "private" ACL, direct access via URL may require additional authorization. While Uploadthing's documentation does not explicitly detail signed URLs, the concept aligns with cloud storage practices like Amazon S3, where signed URLs provide temporary access to private files. Given Uploadthing's mention of being a "better S3" alternative, it seems likely that similar mechanisms exist, but specific implementation details are not provided. Developers may need to:

  • Refer to the storage provider's documentation (if Uploadthing uses an underlying service like S3) or
  • Contact Uploadthing support for guidance on generating signed URLs for sharing private files.

Tables for Clarity

To organize the information, consider the following tables summarizing key aspects:

StepActionDetails
1. Install PackageRun npm install uploadthingInstalls server and client dependencies
2. Environment SetupSet UPLOADTHING_TOKEN=your_tokenSecure SDK interaction with API key
3. File Router CreationDefine routes in src/uploadthing.ts using createUploadthingExample: Image uploader with 4MB limit, private ACL
4. Server IntegrationMount at /api/uploadthing in Express serverUse createRouteHandler for routing
5. Client UsageUse @uploadthing/react for upload button, set endpoint URLExample: https://your-server.com/api/uploadthing
Security AspectDescriptionImplementation
Middleware AuthenticationEnsure only authorized users can upload filesCheck user login status, throw error if unauthorized
Access Control (ACL)Set file access to "public-read" or "private"Configure in route, affects file visibility

Unexpected Findings

An interesting observation is Uploadthing's positioning as an alternative to S3, suggesting it uses similar cloud storage technologies. This implies potential familiarity with concepts like signed URLs, but the lack of explicit documentation on this topic adds complexity, requiring developers to seek additional resources or support.

Conclusion

This guide provides a comprehensive approach to setting up Uploadthing with Express and Typescript, emphasizing security through authentication and access controls. While accessing uploaded files is straightforward via the provided URL, handling private files with signed URLs may require further exploration, potentially through Uploadthing's support channels or underlying storage provider documentation.


Key Citations

2026 © Sachin Thapa. All rights reserved.