Duck Upload
Strategy-based file upload engine with React bindings. Pause, resume, retry, and persist uploads across reloads.
Uploads that survive reloads and flaky networks
Three pieces: a core engine, a strategy contract, and a React hook. Pick a transport, wire it in, and ship resumable uploads with typed progress.
Strategy-based engine
Swap upload backends without touching call sites. Direct, presigned, tus, S3 multipart. One contract, many transports.
Pause + resume
Cancel in-flight uploads and resume from the last committed byte. Built on AbortController and per-chunk commits.
Retries + backoff
Per-chunk retries with exponential backoff. Flaky networks no longer drop partial work.
Persistence adapter
Pluggable persistence for IndexedDB or custom storage. Resume uploads across tab reloads and browser restarts.
React bindings
`useUpload` hook, typed progress events, optimistic UI. Cache-aware state that plays well with React Query.
Zero lock-in
The core is framework-agnostic. Use the React bindings, or wire it into Vue, Solid, or Svelte yourself.
Install
Pick a strategy, hook it into your form.
# Install
bun add @gentleduck/upload
# Use 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.