A chunked file upload demo with a Vite + TypeScript frontend and an Express + MinIO + PostgreSQL backend.
The browser splits files into chunks, uploads each chunk to a presigned URL, then tells the server to assemble them. A file list with select-and-delete is included.
# Frontend
bun install
bun run dev # starts Vite on http://localhost:5173
# Backend (separate terminal)
cd backend
bun install
bun run dev # starts Express on http://localhost:8080The backend also needs PostgreSQL and MinIO running locally — see backend/README.md for details.
| File | Purpose |
|---|---|
| index.html | Single page shell with file input, list, and toolbar |
| client.ts | DOM wiring — connects buttons/input to files.ts exports |
| files.ts | File list state, init/complete/abort flow, delete, refresh |
| file-upload.ts | Chunked upload with exponential backoff + jitter retries |
| css.css | Styles |
- User picks a file via the
+button. files.tscallsPOST /upload/initwith file metadata → receives anuploadIdand presigned PUT URLs.file-upload.tsslices the file into chunks and uploads them in parallel (up to 5 retries each with exponential backoff).- On success,
files.tscallsPOST /upload/completewith the part ETags to assemble the file. - On failure, the client calls
POST /upload/abortto clean up the multipart session and rethrows the error. - The file list (
GET /files) shows completed uploads; selected files can be deleted (POST /files/delete).
- Frontend: TypeScript, Vite, vanilla DOM
- Backend: Express, MinIO (S3-compatible), PostgreSQL — see backend/README.md