feat: Add Convex Adapter
Summary
- This PR adds Convex adapter.
- This repo is an example for how to implement it.
- It was highly inspired from PR #929.
- New Convex adapter entrypoints
packages/uploadthing/src/convex.tspackages/uploadthing/src/convex-helpers.ts
Design decisions
- Internal action boundary: Keep UploadThing’s core handler pure over
Request/Response, and adapt at the Convex boundary usinginternalActionGeneric. Mirrors existing framework adapters and avoids Convex-specific leakage. - Request envelope: Convex internal actions require serializable args; we pass
{ url, method, headers, body? }and reconstruct aRequestinside the action. - CORS handling: Uses convex-helpers corsRouter to handle cors
Developer experience
Usage sketch:
// convex/http.ts
import corsRouter from "convex-helpers/server/cors";
import { httpRouter } from "convex/server";
import { createRouteHandler } from "uploadthing/convex-helpers";
import { internal } from "./_generated/api";
const http = httpRouter();
const cors = corsRouter(http, {
allowedOrigins: ["http://localhost:3000"],
});
createRouteHandler({
http: cors,
internalAction: internal.uploadthing.handler,
path: "/api/uploadthing",
});
export default http;
// convex/uploadthing.ts
"use node";
import { createInternalAction, createUploadthing, FileRouter } from "uploadthing/convex";
import { api } from "./_generated/api";
import crypto from "node:crypto";
// globalThis.crypto is not defined in convex
globalThis.crypto = crypto as Crypto;
const f = createUploadthing();
const router = {
imageUploader: f({ image: { maxFileSize: "4MB" } })
.middleware(async (opts) => {
const identity = await opts.ctx.auth.getUserIdentity();
return { userId: identity?.subject };
})
.onUploadComplete(async (opts) => {
await opts.ctx.runMutation(api.media.add, { url: opts.file.ufsUrl });
return { uploadedBy: opts.metadata.userId };
}),
} satisfies FileRouter;
export type OurFileRouter = typeof router;
export const handler = createInternalAction({ router });
Required env on convex:
UPLOADTHING_TOKEN
Thanks for taking a look! I’m happy to iterate on naming, paths, or API surface to fit project.
Summary by CodeRabbit
-
New Features
- Convex backend adapter: upload builders, internal action bridge, and HTTP route helper; optional Convex peer support.
-
Documentation
- New Convex integration guide, docs page, navigation entry, and Convex logo/icon added.
-
Examples
- Minimal Next.js + Convex example with upload routes, handlers, schema, and client wiring.
-
Chores
- Build and publish config updated to include Convex artifacts and example assets.
🦋 Changeset detected
Latest commit: 75f4383695af312f028b3257b3d65733cf1aebcc
The changes in this PR will be included in the next version bump.
This PR includes changesets to release 1 package
| Name | Type |
|---|---|
| uploadthing | Minor |
Not sure what this means? Click here to learn what changesets are.
Click here if you're a maintainer who wants to add another changeset to this PR
Walkthrough
Adds a Convex backend adapter for UploadThing: new source modules (convex, convex-helpers), package exports and optional peer dependencies for convex/convex-helpers, build and declaration config updates, docs, and a minimal Convex example app wiring UploadThing through a Convex internal action and HTTP router.
Changes
| Cohort / File(s) | Summary |
|---|---|
Package exports & publishingpackages/uploadthing/package.json |
Adds exports entries ./convex and ./convex-helpers (ESM/CJS + types), includes convex and convex-helpers in files, and declares them as optional peerDependencies. |
Build / declaration configpackages/uploadthing/tsdown.config.ts,packages/uploadthing/turbo.json |
Adds tsdown entries mapping ../convex/index → src/convex.ts and ../convex-helpers/index → src/convex-helpers.ts; adds convex/** and convex-helpers/** to turbo build outputs. |
Convex integration sourcepackages/uploadthing/src/convex.ts,packages/uploadthing/src/convex-helpers.ts |
New Convex adapter implementation: createUploadthing builder, createInternalAction (adapts UploadThing handlers to Convex internal actions), and createRouteHandler HTTP bridge registering OPTIONS/GET/POST and forwarding requests to Convex actions. |
Documentation pagedocs/src/app/(docs)/backend-adapters/convex/page.mdx |
New docs page describing Convex adapter setup, FileRouter example, server wiring, HTTP mounting, and client usage. |
Docs UI & navdocs/src/components/icons.tsx, docs/src/components/Libraries.tsx, docs/src/site-config.ts |
Adds ConvexIcon, inserts Convex into Backend Adapters list and site navigation, and adjusts the adapters grid layout. |
Changeset.changeset/swift-beds-explain.md |
Adds changeset noting a minor version bump and Convex adapter addition. |
Example project metadataexamples/minimal-convex/package.json, examples/minimal-convex/next.config.js, examples/minimal-convex/tsconfig.json, examples/minimal-convex/next-env.d.ts, examples/minimal-convex/.env.example, examples/minimal-convex/.gitignore, examples/minimal-convex/README.md |
New Next.js + Convex example project with scripts, env example, gitignore, README, and TS/Next config. |
Example Convex backendexamples/minimal-convex/convex/* |
Adds Convex schema, http router (http.ts) using createRouteHandler, media mutation, UploadThing internal action/router (uploadthing.ts), Convex tsconfig, and example README. |
Example Next.js UIexamples/minimal-convex/src/app/layout.tsx, examples/minimal-convex/src/app/page.tsx, examples/minimal-convex/src/utils/uploadthing.ts |
Adds RootLayout with UploadThing SSR plugin, example page demonstrating UploadButton/Dropzone and manual upload flows, and typed helper exports (UploadButton, UploadDropzone, useUploadThing) configured to Convex site URL. |
Sequence Diagram(s)
sequenceDiagram
autonumber
actor User as Client
participant Browser as Browser
participant ConvexHTTP as Convex HTTP Router
participant Bridge as createRouteHandler
participant InternalAction as Convex internalAction
participant Adapter as adapter handler (makeAdapterHandler)
participant UT as UploadThing router
User->>Browser: Start upload
Browser->>ConvexHTTP: POST /api/uploadthing
Note right of ConvexHTTP #f3f3f3: OPTIONS route returns 204 for preflight
ConvexHTTP->>Bridge: matched route
Bridge->>InternalAction: ctx.runAction(internalAction, { request })
InternalAction->>Adapter: construct Request and invoke adapter handler
Adapter->>UT: Dispatch to UploadThing router
UT-->>Adapter: Response { status, statusText, headers, body }
Adapter-->>InternalAction: return Response-like object
InternalAction-->>Bridge: plain result forwarded
Bridge-->>ConvexHTTP: respond with action-derived status, headers, body
ConvexHTTP-->>Browser: HTTP response
Estimated code review effort
🎯 4 (Complex) | ⏱️ ~45 minutes
Suggested labels
uploadthing/client
Suggested reviewers
- markflorkowski
- juliusmarminge
📜 Recent review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📥 Commits
Reviewing files that changed from the base of the PR and between f840666af289fd80d4d70fd8544506281776dac5 and 75f4383695af312f028b3257b3d65733cf1aebcc.
📒 Files selected for processing (1)
examples/minimal-convex/convex/http.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- examples/minimal-convex/convex/http.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Vade Review
✨ Finishing Touches
- [ ] 📝 Generate Docstrings
🧪 Generate unit tests
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
🪧 Tips
Chat
There are 3 ways to chat with CodeRabbit:
- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
I pushed a fix in commit <commit_id>, please review it.Open a follow-up GitHub issue for this discussion.
- Files and specific lines of code (under the "Files changed" tab): Tag
@coderabbitaiin a new review comment at the desired location with your query. - PR comments: Tag
@coderabbitaiin a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
Support
Need help? Create a ticket on our support page for assistance with any issues or questions.
CodeRabbit Commands (Invoked using PR/Issue comments)
Type @coderabbitai help to get the list of available commands.
Other keywords and placeholders
- Add
@coderabbitai ignoreor@coderabbit ignoreanywhere in the PR description to prevent this PR from being reviewed. - Add
@coderabbitai summaryto generate the high-level summary at a specific location in the PR description. - Add
@coderabbitaianywhere in the PR title to generate the title automatically.
CodeRabbit Configuration File (.coderabbit.yaml)
- You can programmatically configure CodeRabbit by adding a
.coderabbit.yamlfile to the root of your repository. - Please see the configuration documentation for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation:
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
Status, Documentation and Community
- Visit our Status Page to check the current availability of CodeRabbit.
- Visit our Documentation for detailed information on how to use CodeRabbit.
- Join our Discord Community to get help, request features, and share feedback.
- Follow us on X/Twitter for updates and announcements.
@IslamIhab is attempting to deploy a commit to the Ping Labs Team on Vercel.
A member of the Team first needs to authorize it.
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
| Project | Deployment | Preview | Comments | Updated (UTC) |
|---|---|---|---|---|
| legacy-docs-uploadthing | Sep 4, 2025 0:03am |
Needs docs and examples.
@markflorkowski Added docs and example
@markflorkowski Sorry for spamming but could I get a review? If the PR is a bit too bit I can break it down to several smaller PRs to make each part take less time
I would love to see this getting merged soon. @IslamIhab Great work man!
+1
bump for this, really need it asap
+1