Uploads that survive bad networks
A file upload engine with React bindings. Pause, resume, and retry uploads, and pick them up again after a reload.
Swappable strategies
Direct, presigned, tus, or S3 multipart behind one contract. Change backends without touching call sites.
Pause and resume
Stop an upload and resume from the last committed byte. Built on AbortController and per-chunk commits.
Retries with backoff
Each chunk retries with exponential backoff, so a flaky network doesn’t throw away finished work.
Persistence
Store progress in IndexedDB or your own storage. Uploads resume after a tab reload or a browser restart.
React bindings
A
useUploadhook with typed progress events and optimistic UI. It works well alongside React Query.No lock-in
The core is framework-agnostic. Use the React bindings, or wire it into Vue, Solid, or Svelte yourself.
Install
Pick a strategy and connect it to your form.
Install
bun add @gentleduck/uploadUse it
import { useUpload } from '@gentleduck/upload/react' import { directStrategy } from '@gentleduck/upload/strategies' const { upload, progress, pause, resume } = useUpload({ strategy: directStrategy({ endpoint: '/api/upload' }), })
Free & open source
gentleduck is MIT licensed and will always be free and open source. Every package ships with full source access — fork it, modify it, own it.