Works with any backend npm install Zero dependencies

First-class React component via multipleupload/react

A thin React wrapper that owns the lifecycle (mount -> instantiate -> tear-down on unmount), forwards every core event as a same-named on* prop, and exposes the imperative instance via instanceRef. Works with React 16.8+ through 19. Zero React-specific options - anything you can pass to new MultipleUpload(...) goes through options.

Subpath import: multipleupload/react ships in the same npm package - no separate install. Subpath exports keep the React peer-dependency optional so non-React consumers don't pull anything extra.
Install
npm install multipleupload react react-dom
Component usage
import { MultipleUpload } from 'multipleupload/react';
import 'multipleupload/multipleupload.css';

export default function UploadPanel() {
 return (
 <MultipleUpload
 options={{
 uploadUrl: '/api/upload',
 multiple: true,
 autoUpload: false,
 strategy: 'chunked',
 chunkSize: 5 * 1024 * 1024,
 chunkConcurrency: 4
 }}
 onTaskComplete={(task, result) => {
 console.log('uploaded', result.fileGuid, result.fileName);
 }}
 onTaskProgress={(task) => {
 console.log(task.fileName, task.progress + '%');
 }}
 onError={(err) => console.error(err)}
 />
 );
}
Imperative access via ref
import { useRef } from 'react';
import { MultipleUpload } from 'multipleupload/react';

export default function ManualSubmit() {
 const upRef = useRef(null);
 return (
 <>
 <MultipleUpload instanceRef={upRef} options={{ uploadUrl: '/api/upload', autoUpload: false }} />
 <button onClick={() => upRef.current?.upload()}>Start upload</button>
 <button onClick={() => upRef.current?.openImageEditor(file)}>Edit image</button>
 </>
 );
}
Forwarded events

Every event the core emits maps to a same-named React callback prop:

onTaskAdded, onTaskRemoved, onTaskStarted, onTaskProgress, onTaskComplete,
onTaskFailed, onTaskCancelled, onTaskPaused, onTaskResumed,
onQueueComplete, onAllComplete, onProgress, onStateRestored, onError
Hook recipe: tracking upload progress in component state
import { useState } from 'react';
import { MultipleUpload } from 'multipleupload/react';

export default function ProgressBar() {
 const [pct, setPct] = useState(0);
 return (
 <>
 <MultipleUpload
 options={{ uploadUrl: '/api/upload', multiple: true }}
 onProgress={(o) => setPct(o.progress)}
 />
 <div>Overall: {pct}%</div>
 </>
 );
}
Why this beats DIY useEffect
  • Cleanup is handled - no leaked uploaders on hot-reload or route changes.
  • Event handlers re-read from the latest render via a ref, so you don't need to memoize callbacks.
  • The instance ref pattern lets parent components drive imperative actions (manual submit, pause-all, image editor) without re-renders.