A headless upload engine with native, DOM-identical UI packages for React, Vue, Svelte, Angular, Vanilla JS, and Preact — with optional server-mode uploads, cloud drives, camera, screen capture, and link imports.
Website · Docs · Live Demo · Discord
upup is a free, MIT-licensed file uploader built as one headless
@useupup/core engine with a matching native UI for every major
framework. React is the visual canon; the Vue, Svelte, Angular, Vanilla, and
Preact ports render the same DOM with the same props, verified by a
cross-framework parity harness (structure, classes, accessibility attributes,
text). Uploads go straight from the browser to any S3-compatible storage over
presigned URLs, signed either by a route you write (Client Mode) or by
@useupup/server on your backend, with an HMAC-signed trust
model and server-side cloud-drive OAuth (Server Mode).
Pick the package for your framework — the component API and the rendered DOM contract are identical across all of them:
| Package | Install | Get started |
|---|---|---|
@useupup/react |
npm i @useupup/react |
React quickstart |
@useupup/vue |
npm i @useupup/vue |
Vue quickstart |
@useupup/svelte |
npm i @useupup/svelte |
Svelte quickstart |
@useupup/angular |
npm i @useupup/angular |
Angular quickstart |
@useupup/vanilla |
npm i @useupup/vanilla |
Vanilla quickstart |
@useupup/preact |
npm i @useupup/preact |
Preact quickstart |
@useupup/next |
npm i @useupup/next |
Client re-export + /server route handlers (App & Pages routers) |
@useupup/core |
npm i @useupup/core |
Headless engine — state, pipeline, drive plugins, i18n, theme |
@useupup/server |
npm i @useupup/server |
Server Mode — S3 presign/multipart, drive OAuth, HMAC trust model |
import { UpupUploader } from '@useupup/react'
import '@useupup/react/styles'
export default function Uploader() {
return <UpupUploader provider="aws" uploadEndpoint="/api/upload-token" />
}Client Mode uploads directly from the browser to your storage; your server only
issues short-lived presigned URLs at uploadEndpoint — a route you provide,
either a small presign handler of your own or @useupup/server's
createUpupHandler (see Server mode below). The stylesheet is a
separate import so projects without Tailwind get the same look. Every other
framework mounts the same component with the same props — see the per-framework
quickstarts in the install table above.
Let your own backend sign every upload and run cloud-drive OAuth, so storage
credentials and drive OAuth tokens never reach the browser. File bytes still go
straight from the browser to your bucket over presigned URLs; drive files stream
from your server into the bucket. createUpupHandler mounts on any Node or edge
framework and enforces an HMAC-signed trust model — uploadTokenSecret is
required and must be at least 16 characters:
// app/api/upup/[...route]/route.ts (Next.js App Router)
import { createUpupHandler } from '@useupup/server'
const handler = createUpupHandler({
storage: {
type: 'aws',
bucket: process.env.S3_BUCKET!,
region: process.env.S3_REGION!,
},
uploadTokenSecret: process.env.UPUP_UPLOAD_TOKEN_SECRET!, // required · stable · high-entropy · >=16 chars
})
export const GET = handler
export const POST = handlerS3 credentials resolve from the standard AWS environment
(AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY or an IAM role), or you can pass
accessKeyId / secretAccessKey explicitly. Then point the uploader at the handler:
<UpupUploader mode="server" serverUrl="/api/upup" provider="aws" />Express, Fastify, and Hono handlers ship as subpath exports
(@useupup/server/express, @useupup/server/fastify, @useupup/server/hono), and
@useupup/next wraps both the App and Pages routers.
Full docs → useupup.com/docs/getting-started · Server Mode setup →
apps/landing/content/docs/guides/server-mode-setup.mdx
- Headless core.
@useupup/coreis a zero-framework-dependency engine: file state, an upload pipeline (compression, HEIC→JPEG, EXIF stripping, checksums, thumbnails, optional Web Worker offload), cloud-drive plugins, i18n, and theming. Build your own UI on it, or use a native package. - Native UI for six frameworks. React, Vue, Svelte, Angular, Vanilla JS, and Preact — same DOM structure, same
upup-classes, enforced by a cross-framework parity harness. - Client or Server mode. Direct browser → storage presigned uploads in both: sign them with a route you write, or let
@useupup/serversign them with an HMAC-signed trust model (signed length, key/uploadId binding, mandatory secrets) and run cloud drives server-side. - S3-compatible storage. AWS S3, Cloudflare R2, MinIO, DigitalOcean Spaces, Backblaze B2, Wasabi — any S3-compatible endpoint.
- Cloud drives. Import from Google Drive, OneDrive, Dropbox, and Box, in client or server mode.
- More sources. Drag-and-drop, file picker, camera, screen capture, audio recording, and link (URL) import.
- Resumable uploads. Optional for large files, in two forms: S3 multipart through
@useupup/server, which resumes at the last completed part after a reload or crash, or tus against an external tus server, loaded on demand so it never weighs down the core bundle. - Image editor. Crop, rotate, and annotate before upload (React / Preact only).
- i18n & theming. ICU-based localization with 9 bundled locales and RTL support, plus a slot-level theming system that targets every rendered element.
- TypeScript-first. Full type definitions out of the box.
Both apps below run the upup v3.1 engine under its previous @upupjs/* scope —
the same codebase, published before the rename to @useupup/*.
- uNotes — AI doc uploads for past exams → unotes.net
- Shorty — media uploads for transcripts → aishorty.com
PRs welcome. Please read CONTRIBUTING.md and our Code of Conduct. Found a vulnerability? See the Security Policy.
This repo is a pnpm workspace driven by Turborepo.
upup/
├── packages/core/ # @useupup/core — headless engine (state, pipeline, drives, i18n, theme)
├── packages/react/ # @useupup/react — canonical UI
├── packages/vue/ # @useupup/vue — native Vue port (DOM-identical to react)
├── packages/svelte/ # @useupup/svelte — native Svelte port
├── packages/angular/ # @useupup/angular — native Angular port
├── packages/vanilla/ # @useupup/vanilla — framework-free port
├── packages/preact/ # @useupup/preact — preact/compat re-export of react
├── packages/next/ # @useupup/next — client re-export + /server route handlers
├── packages/server/ # @useupup/server — server-mode endpoints (S3 presign/multipart, drive OAuth)
├── apps/playground/ # Main dev app
├── apps/landing/ # Marketing site (useupup.com) + docs served at /docs (fumadocs; MDX in content/docs)
├── apps/e2e-test/ # Playwright: deep React suite + cross-framework parity harness
└── turbo.json # Build pipeline
git clone https://github.com/DevinoSolutions/upup.git
cd upup
nvm use # Node 20.20.2, pinned in .nvmrc
pnpm install
pnpm dev # landing + docs + playground + package watchers, via Turborepo| Command | Description |
|---|---|
pnpm dev |
Run everything in watch mode |
pnpm build |
Build all packages + apps |
pnpm test |
Run every package's vitest suite |
pnpm typecheck |
tsc --noEmit across every package |
Releases go through changesets:
pushes to master open a release PR and publish the public packages via CI
(.github/workflows/publish.yml).
💬 Discord · 🐛 Issues · 🌐 Website
MIT License · Made with ❤️ by Devino