Skip to content

Quick Start

This guide gets you from zero to a working video upload UI in about 20 lines of React.

Prerequisites

  • React 18+
  • Packages installed (see Installation)
  • A Hyperserve account (Free or Pay Per Use) and API key (for the example below)
import { createHyperserveConfig } from "@hyperserve/upload-adapter-hyperserve";
import {
UploadProvider,
composeValidators,
maxFileSize,
allowedTypes,
} from "@hyperserve/upload";
import {
DropZone,
FileList,
FileListToolbar,
ViewModeProvider,
} from "@hyperserve/upload-react";
// These three callbacks call YOUR backend, which holds your Hyperserve API key.
// The adapter handles the actual file upload to storage directly via the SDK,
// but createUpload/completeUpload/getVideoStatus talk to the Hyperserve management
// API, so they must be proxied server-side to keep your API key out of the browser.
const config = createHyperserveConfig({
createUpload: async (file, options) =>
fetch("/api/create-upload", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: file.name, size: file.size, ...options }),
}).then((r) => r.json()),
completeUpload: async (videoId) => {
await fetch(`/api/complete-upload/${videoId}`, { method: "POST" });
},
getVideoStatus: async (videoId) =>
fetch(`/api/video-status/${videoId}`).then((r) => r.json()),
uploadOptions: {
isPublic: true,
resolutions: ["480p", "1080p"],
},
validate: composeValidators(
maxFileSize(500 * 1024 * 1024),
allowedTypes(["video/*"]),
),
});
function App() {
return (
<UploadProvider config={config}>
<ViewModeProvider>
<DropZone supportingText="MP4, WebM, MOV, up to 500 MB" />
<FileListToolbar right={<FileListToolbar.ViewToggle />} />
<FileList />
</ViewModeProvider>
</UploadProvider>
);
}
  1. createHyperserveConfig wires up the Hyperserve adapter, status checker, and your validation rules into a single config object. The adapter calls putVideoToStorage from the Hyperserve SDK directly to stream the file to cloud storage; no backend is needed for that part. However, createUpload, completeUpload, and getVideoStatus must talk to the Hyperserve management API using your API key, which can’t be exposed in the browser. Those three callbacks are thin fetches to your own backend routes, which hold the key and proxy the calls to Hyperserve.
  2. UploadProvider manages the upload state machine: file queue, concurrency, progress, abort/retry.
  3. ViewModeProvider provides list/grid toggle state to the UI components.
  4. DropZone handles drag-and-drop and file picker input.
  5. FileList renders each file with progress bars, status badges, and action buttons.

All components read from the UploadProvider context. No prop drilling required.

The three callbacks (createUpload, completeUpload, and getVideoStatus) must run server-side to keep your Hyperserve API key out of the browser. Each route must implement the following contract:

RouteReceivesReturns
POST /api/create-upload{ name: string, size: number, ...uploadOptions }{ videoId: string }
POST /api/complete-upload/:id(none)204 / empty body
GET /api/video-status/:id(none){ status: string, ... }
Terminal window
git clone https://github.com/hyper-serve/upload
cd upload/examples/web
cp .env.example .env # add your Hyperserve API key
bun install && bun dev