# Getting Started

upup is a file uploader with a native UI for **React, Vue, Svelte, Angular,
Vanilla JS, and Preact**, built on a shared headless core (`@useupup/core`), with
an optional server mode for signed uploads and cloud-drive sources (Google
Drive, OneDrive, Dropbox, Box). Every package renders the same UI.

Here is the uploader you are about to install — try it:

<DocsUploaderDemo />

This guide uses React. To start from another framework, use its quickstart —
each mounts the same uploader with the same options:

- [React quickstart](/docs/quickstarts/react/)
- [Vue quickstart](/docs/quickstarts/vue/)
- [Svelte quickstart](/docs/quickstarts/svelte/)
- [Angular quickstart](/docs/quickstarts/angular/)
- [Vanilla JS quickstart](/docs/quickstarts/vanilla/)
- [Preact quickstart](/docs/quickstarts/preact/)

Install the React package and styles:

```bash
npm i @useupup/react
```

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

## Pick your framework

The same uploader mounts from every package with the same options. Pick your
framework — the choice is remembered as you move through the docs, and you can
deep-link a framework with `?fw=vue`.

<FrameworkTabs topic="getting-started" />

## Local file collection

With no upload target, upup lets users select files and gives you `File`
objects through callbacks and hooks.

```tsx
<UpupUploader
    sources={['local', 'url']}
    onFilesSelected={files => {
        console.log(files)
    }}
/>
```

Calling `upload()` without a target returns a typed no-target error.

## What happens to your file

Whichever target you pick, every file runs through the same client-side pipeline
before it leaves the browser — validated, optionally compressed (HEIC images are
converted), then uploaded, with the heavy work offloaded to a web worker.

<PipelineDiagram />

## Client uploads

Use `uploadEndpoint` when your app signs upload URLs and the browser uploads
bytes directly to storage.

```tsx
<UpupUploader
    provider="aws"
    uploadEndpoint="/api/upload-token"
    metadata={{ projectId: 'p_123' }}
/>
```

## Server uploads

Use `@useupup/server` when provider OAuth, token storage, storage credentials,
or transfer policy should live server-side.

```bash
npm i @useupup/react @useupup/server
```

```tsx
<UpupUploader provider="aws" mode="server" serverUrl="/api/upup" />
```

```ts
import { createUpupHandler, InMemoryTokenStore } from '@useupup/server'

const handler = createUpupHandler({
    storage: {
        type: 'aws',
        bucket: process.env.S3_BUCKET!,
        region: process.env.S3_REGION!,
    },
    // Required, server-only: a stable, high-entropy secret (min 16 chars),
    // shared across every server instance. createUpupHandler throws without it.
    uploadTokenSecret: process.env.UPUP_UPLOAD_TOKEN_SECRET!,
    tokenStore: new InMemoryTokenStore(),
    getUserId: async () => 'user_123',
})

export const GET = handler
export const POST = handler
```

<PlaygroundCta />
