# Set up upup in this project

These are official instructions from upup to set up an AI development environment for upup, the MIT-licensed, self-hosted file uploader with native UI packages for React, Vue, Svelte, Angular, Vanilla JS, and Preact. All commands are validated by upup. Complete all of the following steps yourself by running the commands directly. Do not ask the user to run any of these commands.

1. Detect the project framework and package manager
2. Install the matching @useupup/* package
3. Mount the uploader with the recommended client-mode config
4. Add the presigned-URL route the uploader calls
5. Save the upup context block into your agent's instructions file
6. Verify the project builds and report what was set up

upup is an npm library. There is no API key, hosted service, MCP server, or CLI to install — setup means installing the right package, wiring it into the project, and carrying an accurate model of the library in your instructions file.

## Step 1: Detect the framework and package manager

Read `package.json`. Pick exactly ONE framework section from Step 2 using its detection rule (check `next` before `react`, because a Next.js project also depends on React). Use the project's package manager: `pnpm-lock.yaml` → pnpm, `yarn.lock` → yarn, `bun.lockb` or `bun.lock` → bun, otherwise npm. Translate the `npm i` commands below accordingly (`pnpm add`, `yarn add`, `bun add`).

If the project has no package.json, stop and ask the user which framework they want before continuing.

## Step 2: Install and mount the package for the detected framework

Requirements: Node 20+. React packages need React 19; @useupup/next needs Next.js 15+.

### Next.js — `@useupup/next`

Use this section when the project has `next` in package.json dependencies. Quickstart: https://useupup.com/docs/quickstarts/next/

```sh
npm i @useupup/next
```

Mount the uploader (client mode — the browser uploads straight to your storage):

```tsx
'use client'

import { UpupUploader } from '@useupup/next'
import '@useupup/next/styles'

export default function Uploader() {
    return <UpupUploader provider="aws" uploadEndpoint="/api/upload-token" />
}
```

### React — `@useupup/react`

Use this section when the project has `react` (19+) in package.json dependencies and no `next`. Quickstart: https://useupup.com/docs/quickstarts/react/

```sh
npm i @useupup/react
```

Mount the uploader (client mode — the browser uploads straight to your storage):

```tsx
import { UpupUploader } from '@useupup/react'
import '@useupup/react/styles'

export default function Uploader() {
    return <UpupUploader provider="aws" uploadEndpoint="/api/upload-token" />
}
```

### Vue — `@useupup/vue`

Use this section when the project has `vue` (3+) in package.json dependencies. Quickstart: https://useupup.com/docs/quickstarts/vue/

```sh
npm i @useupup/vue
```

Mount the uploader (client mode — the browser uploads straight to your storage):

```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>
```

### Svelte — `@useupup/svelte`

Use this section when the project has `svelte` (5+) in package.json dependencies. Quickstart: https://useupup.com/docs/quickstarts/svelte/

```sh
npm i @useupup/svelte
```

Mount the uploader (client mode — the browser uploads straight to your storage):

```svelte
<script lang="ts">
    import { UpupUploader } from '@useupup/svelte'
    import '@useupup/svelte/styles'
</script>

<UpupUploader provider="aws" uploadEndpoint="/api/upload-token" />
```

### Angular — `@useupup/angular`

Use this section when the project has `@angular/core` (17+) in package.json dependencies. Quickstart: https://useupup.com/docs/quickstarts/angular/

```sh
npm i @useupup/angular
```

Mount the uploader (client mode — the browser uploads straight to your storage):

```ts
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.
```

### Preact — `@useupup/preact`

Use this section when the project has `preact` in package.json dependencies. Quickstart: https://useupup.com/docs/quickstarts/preact/

```sh
npm i @useupup/preact
```

Mount the uploader (client mode — the browser uploads straight to your storage):

```tsx
import { UpupUploader } from '@useupup/preact'
import '@useupup/preact/styles'

export function Uploader() {
    return <UpupUploader provider="aws" uploadEndpoint="/api/upload-token" />
}
```

### Vanilla JS — `@useupup/vanilla`

Use this section when the project has no framework dependency at all. Quickstart: https://useupup.com/docs/quickstarts/vanilla/

```sh
npm i @useupup/vanilla
```

Mount the uploader (client mode — the browser uploads straight to your storage):

```ts
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()
```

## Step 3: Add the presigned-URL route

In client mode the uploader POSTs to `uploadEndpoint` once per file and expects a presigned upload URL back; the browser then PUTs the bytes straight to the bucket. Add a route at `/api/upload-token` in the project's server framework. A ready-to-copy handler for every supported storage provider is at https://useupup.com/docs/code-examples/ — fetch it and adapt the route to the project. Read the bucket name, region, and credentials from environment variables; never hardcode them. If the project has no server at all (a pure static SPA), skip this step and tell the user the route is still needed before uploads work.

If the user wants uploads and cloud-drive OAuth proxied through their own server instead, install `@useupup/server` and follow https://useupup.com/docs/guides/server-mode-setup/ — `createUpupHandler` requires an `uploadTokenSecret` of at least 16 characters and throws at construction without it.

## Step 4: Save the upup context block

This is the compact, verified model of upup that keeps later edits correct. Use the section for the agent you are running as.

```text
# 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/
```

### Claude Code

Write the context block above into `CLAUDE.md` 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). Then re-read the file to confirm the block is present.

### Codex

Write the context block above into `AGENTS.md` 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). Then re-read the file to confirm the block is present.

### Cursor

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.

### OpenCode

Write the context block above into `AGENTS.md` 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). Then re-read the file to confirm the block is present.

### Other agents

Write the same block into whichever project-instructions file your agent reads (for example `AGENTS.md` or `.github/copilot-instructions.md`).

## Step 5: Verify

Run the project's type-check or build (`npm run build`, or the equivalent for its package manager). Success looks like: the build completes, the `@useupup/*` package resolves, and the stylesheet import resolves. If the build fails on the styles import, the package's `styles` subpath needs TypeScript 5.7+ / `moduleResolution: "bundler"`; tell the user rather than removing the import.

## Step 6: Report to the user

Print this summary, filled in:

```text
upup is set up.
- Installed: <package>@<version>
- Mounted: <path to the component or file that renders the uploader>
- Presign route: <path> (reads bucket/region/credentials from env)
- Agent context: <instructions file> now carries the upup context block
Still yours to do:
- Set the storage env vars used by the presign route
- Choose sources / cloud drives via the `sources` and `cloudDrives` props (see the quickstart)
```

## Resources

- Docs home: https://useupup.com/docs/
- FAQ: https://useupup.com/docs/faq/
- llms.txt: https://useupup.com/llms.txt
- llms-full.txt: https://useupup.com/llms-full.txt
- Server mode setup: https://useupup.com/docs/guides/server-mode-setup/
- API reference: https://useupup.com/docs/api-reference/upupuploader/required-props/
- Code examples: https://useupup.com/docs/code-examples/
- Support: https://useupup.com/support/
- GitHub: https://github.com/DevinoSolutions/upup
