FAQs
Frequently asked questions about @gentleduck/upload.
Is React required?
No. The core engine is framework-agnostic. You can use @gentleduck/upload/core and @gentleduck/upload/strategies without React. The React bindings in @gentleduck/upload/react are an optional, thin adapter layer.
Does it support S3/MinIO uploads?
Yes. The POST strategy handles S3-style presigned form uploads, and the multipart strategy supports S3/MinIO-style chunked uploads with per-part signing.
Are uploads resumable?
It depends on the strategy. The multipart strategy is resumable -- it persists cursor state after each part, so uploads can continue after a page refresh or network interruption. The POST strategy is not resumable.
How does persistence work?
When persistence is configured, the engine serializes in-progress upload state (intent + cursor) to your chosen storage adapter (localStorage, IndexedDB, or in-memory). On page load, items are restored in a paused state. Since files cannot be serialized, you need to use the rebind command to re-attach the file before resuming.
What happens when an upload fails?
The engine uses a centralized retry policy (retryDecision). By default, uploads are retried up to 3 times. If all attempts are exhausted, the item transitions to an error state. You can configure maxAttempts in the store config.
Can I use a custom upload protocol?
Yes. Create a strategy that implements the start(ctx) method and register it with the strategy registry. Your backend's createIntent should return an intent with a matching strategy field.
How does deduplication work?
If your UploadApi implements findByChecksum, the engine checks for existing files before uploading. When a match is found, the item is completed immediately via a dedupe.ok event without creating a synthetic intent.
What transport does it use?
The default transport uses XHR (createXHRTransport) because it supports upload progress events. You can provide a custom transport implementation if needed.
How does concurrency work?
The scheduler respects the maxConcurrentUploads config (default: 3). When an upload slot opens, the next queued item is started. You can adjust this value based on your backend capacity.
Can I auto-start uploads?
Yes. Pass an autoStart function in the config that receives the upload purpose and returns true for purposes that should start automatically:
const store = createUploadStore({
api,
strategies,
config: {
autoStart: (purpose) => purpose === 'avatar',
},
})const store = createUploadStore({
api,
strategies,
config: {
autoStart: (purpose) => purpose === 'avatar',
},
})What is the difference between createUploadStore and createUploadClient?
They are the same. createUploadClient is a thin alias for createUploadStore to match the "Upload Query" mental model.