Set up upup with Cursor
Paste the sentence below into Cursor. It fetches the setup prompt and runs every step itself; this page shows what those steps are.
What you get
- The right package for your framework, installed with your package manager: @useupup/next, @useupup/react, @useupup/vue, @useupup/svelte, @useupup/angular, @useupup/preact, @useupup/vanilla.
- The uploader mounted in client mode with the recommended config, plus the presigned-URL route it calls.
- A verified upup context block written to
.cursor/rules/upup.mdcso later edits stay correct.
Where Cursor saves the context
Write the context block above into `.cursor/rules/upup.mdc` at the project root (create the file if it does not exist; if it exists, append the block under a `## upup` heading without changing anything else). Start the file with this front matter: ```yaml --- description: upup file uploader — packages, modes, and wiring alwaysApply: false globs: ["**/*.tsx", "**/*.ts", "**/*.vue", "**/*.svelte"] --- ``` Then re-read the file to confirm the block is present.
# upup — MIT self-hosted file uploader (docs: https://useupup.com/docs/)
upup is one headless core plus native UI packages for six frameworks; every package renders the same uploader.
Nine published @useupup/* packages:
- @useupup/core headless engine: file state, upload pipeline (compression, HEIC, web-worker), cloud-drive plugins, i18n, theme. Zero framework deps.
- @useupup/react canonical UI (React 19). @useupup/vue, @useupup/svelte, @useupup/angular, @useupup/vanilla, @useupup/preact are native ports with the same DOM.
- @useupup/next Next.js client re-export + /server route handlers (App and Pages routers).
- @useupup/server server-mode endpoints: S3-compatible presign + proxy, cloud-drive token exchange, HMAC-signed upload-token trust model.
Client mode (default): the browser uploads straight to your storage; your app returns presigned URLs at `uploadEndpoint`. No server package required.
React example: import { UpupUploader } from '@useupup/react'; import '@useupup/react/styles'
<UpupUploader provider="aws" uploadEndpoint="/api/upload-token" />
Server mode: point the uploader at @useupup/server with mode="server" serverUrl="/api/upup".
createUpupHandler({ storage: { type: 'aws', bucket, region }, uploadTokenSecret })
— uploadTokenSecret is REQUIRED and must be >= 16 chars, or it throws at construction.
Sources: local drag-and-drop, URL/link import, camera, screen capture, and cloud drives (Google Drive, OneDrive, Dropbox, Box).
Optional: image compression, HEIC conversion, resumable uploads (tus or S3 multipart), ICU i18n, theming. Image editor is React/Preact only.
Quickstarts: https://useupup.com/docs/quickstarts/<react|vue|svelte|angular|vanilla|preact|next>/
Machine-readable docs: https://useupup.com/llms.txt (index) and https://useupup.com/llms-full.txt (full corpus). FAQ: https://useupup.com/docs/faq/Install and mount, per framework
The agent picks exactly one of these from your package.json. The same snippets are in the prompt it runs.
Next.js — @useupup/next
npm i @useupup/next
'use client'
import { UpupUploader } from '@useupup/next'
import '@useupup/next/styles'
export default function Uploader() {
return <UpupUploader provider="aws" uploadEndpoint="/api/upload-token" />
}Next.js quickstartReact — @useupup/react
npm i @useupup/react
import { UpupUploader } from '@useupup/react'
import '@useupup/react/styles'
export default function Uploader() {
return <UpupUploader provider="aws" uploadEndpoint="/api/upload-token" />
}React quickstartVue — @useupup/vue
npm i @useupup/vue
<script setup lang="ts">
import { UpupUploader } from '@useupup/vue'
import '@useupup/vue/styles'
</script>
<template>
<UpupUploader provider="aws" upload-endpoint="/api/upload-token" />
</template>Vue quickstartSvelte — @useupup/svelte
npm i @useupup/svelte
<script lang="ts">
import { UpupUploader } from '@useupup/svelte'
import '@useupup/svelte/styles'
</script>
<UpupUploader provider="aws" uploadEndpoint="/api/upload-token" />Svelte quickstartAngular — @useupup/angular
npm i @useupup/angular
import { Component } from '@angular/core'
import { UpupUploaderComponent } from '@useupup/angular'
@Component({
selector: 'app-uploader',
standalone: true,
imports: [UpupUploaderComponent],
template: `<upup-uploader
[config]="{ provider: 'aws', uploadEndpoint: '/api/upload-token' }"
/>`,
})
export class UploaderComponent {}
// Load the stylesheet once globally: add '@useupup/angular/styles' to the
// `styles` array in angular.json, or `@import '@useupup/angular/styles';`
// in the global styles.css.Angular quickstartPreact — @useupup/preact
npm i @useupup/preact
import { UpupUploader } from '@useupup/preact'
import '@useupup/preact/styles'
export function Uploader() {
return <UpupUploader provider="aws" uploadEndpoint="/api/upload-token" />
}Preact quickstartVanilla JS — @useupup/vanilla
npm i @useupup/vanilla
import { createUploader } from '@useupup/vanilla'
import '@useupup/vanilla/styles'
const uploader = createUploader('#uploader', {
provider: 'aws',
uploadEndpoint: '/api/upload-token',
})
// Later, when you tear down the view:
uploader.destroy()Vanilla JS quickstartVerify
The agent runs your project's build or type-check. Success: the build completes and both the package and its styles import resolve. It then prints what it installed, where the uploader is mounted, and the storage env vars you still need to set.