react-dropzone: a hook-based drop zone for file uploads in React
Simple HTML5 drag-drop zone with React.js.
At a glance
- What is it?
- react-dropzone gives you two prop getters and a hook, not a styled uploader. It is a good fit when you already have an upload pipeline and need the browser's drag-and-drop events wired up correctly.
- Who is it for?
- Adopt react-dropzone if you already own the upload transport and want the drop events, keyboard handling and file filtering handled for you. Do not adopt it if you expected a rendered uploader with progress bars and a queue, because the README shows no such component.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What react-dropzone actually solves for a React file input
A plain `<input type="file">` accepts drops in some browsers and silently ignores them in others, fires no useful state while a drag is over the element, and gives you no hook for filtering files before they reach your code. react-dropzone replaces that with a hook, `useDropzone`, that returns two prop getters. You spread the result of `getRootProps()` onto whatever container you like and the result of `getInputProps()` onto an `<input>`. The library wires the drag events, keeps an `isDragActive` flag, and calls your `onDrop` callback with the accepted files.
The audience is narrow and specific. This is for React developers who already have a place to send files, an S3 presigned URL, a multipart endpoint, a form action, and who want the browser side handled without adopting a full uploader with its own UI and state machine. The README describes it as a "Simple React hook to create a HTML5-compliant drag'n'drop zone for files." That word simple is doing real work: the package ships no rendered component with a progress bar, no retry logic, no queue.
The prop getter pattern and why the ref matters
The design decision that shapes everything else is that react-dropzone does not render anything for you. `getRootProps` and `getInputProps` are functions that return objects of DOM props. You destructure them onto your own elements, which means your markup, your CSS and your accessibility attributes stay yours.
That flexibility has a cost. Because the getters attach a ref internally, the README is explicit: do not set the `ref` prop on the elements where `getRootProps()` or `getInputProps()` are applied. If the component you want to decorate does not forward a ref, both getters accept a custom `refKey` in their parameter object, defaulting to `ref`. The README gives a styled-components example passing `{refKey: "innerRef"}` and a Material UI v4 example that pulls `ref` out of the returned props and hands it to `RootRef`.
The same rule applies to your own props. The README states that any extra props should be passed through `getRootProps` rather than applied to the element, otherwise your props and the internal ones override each other. Handlers you pass in run before the internal ones, so `stopPropagation` inside your `onClick` prevents the built-in behaviour. That ordering is a deliberate escape hatch, and it is the part of the API most likely to surprise someone who skims the examples.
Installing react-dropzone and building a first drop zone
Install from npm. The README notes the package ships as ESM and CommonJS with TypeScript types included and works with any modern bundler such as Vite, webpack or Rspack.
npm install react-dropzoneThe yarn equivalent is documented as well.
yarn add react-dropzoneA minimal zone is the hook plus two spreads. The README's example uses `useCallback` for the drop handler and reads `isDragActive` to swap the prompt text.
import React, {useCallback} from "react";
import {useDropzone} from "react-dropzone";
function MyDropzone() {
const onDrop = useCallback(acceptedFiles => {
// Do something with the files
}, []);
const {getRootProps, getInputProps, isDragActive} = useDropzone({onDrop});
return (
<div {...getRootProps()}>
<input {...getInputProps()} />
{isDragActive ? <p>Drop the files here ...</p> : <p>Drag 'n' drop some files here, or click to select files</p>}
</div>
);
}If you would rather not use a hook directly, the package also exports a `Dropzone` wrapper component that takes `onDrop` and a render-prop child receiving `getRootProps` and `getInputProps`.
The README is also clear about the failure mode here: if you omit the `<input>` element or fail to bind the props from `getInputProps()`, opening a file dialog will not be possible. Drag and drop will still work, clicking will not, and nothing in the library will warn you. Reading the file contents is not part of the package either. The README points at the FileReader API and shows `readAsArrayBuffer` inside a forEach over `acceptedFiles`, with `onabort` and `onerror` handlers left to you.
Where react-dropzone stops and your code has to start
The honest limitation is scope. react-dropzone hands you `File` objects. It does not upload them, does not track progress, does not resume a failed transfer, does not chunk a large file, does not retry, and does not manage a queue across page navigation. Every one of those is your problem, and the README does not pretend otherwise.
There is a second boundary worth naming. The package is a browser-side library. It relies on HTML5 drag-and-drop and the FileReader API, so the README's examples assume a DOM environment. Server-side rendering will render your container, but the drag behaviour is a client concern, and the README does not document an SSR-specific path.
The third boundary is visual. Because the library renders nothing, there is no default styling to override and no built-in progress indicator. Teams that want a drop zone to look like a product surface on day one will spend that time writing CSS and markup themselves. That is the trade: react-dropzone gives you the event plumbing, not the interface.
react-dropzone vs Uppy, FilePond and react-dnd
The alternatives people search for differ from react-dropzone in one consistent way: they own more of the upload.
Uppy is an uploader. It brings a dashboard interface, a plugin system and its own transport layer, so a drop zone is one part of a larger pipeline you adopt wholesale. FilePond takes a similar position with a rendered, styled file input and per-file status. Both are reasonable when you want the whole flow out of the box and are willing to accept their markup and their state model.
react-dropzone sits below that line. It gives you the drop events and the file list, and you keep the transport, the styling and the state. If your upload goes to a signed URL with your own progress UI, that is a feature. If you wanted a finished widget, it is a gap.
react-dnd is a different comparison entirely. It is a general drag-and-drop framework for moving arbitrary items around a UI, including reordering lists and cross-container drags. react-dropzone is narrower: files, from the operating system, into a zone. Choosing react-dnd for a file upload means building the file-type detection and the drop-target semantics yourself.
Maintenance, licence and the cost of upgrading
The repository is not archived, and the last push was on 2026-09-20, one day before this writing. Releases are frequent: v20.1.0 on 2026-08-09, v20.1.1 on 2026-08-20, and v20.1.2 on 2026-09-14. That cadence cuts both ways. You get fixes quickly, and you also get a major-version line that has moved a long way from the older versions still sitting in many tutorials.
The licence is MIT, declared in both the README badge set and the `license` field of package.json. That permits commercial use and modification, but it also means no warranty and no support obligation from the maintainers. The README lists Open Collective backers and sponsors, which is how the project asks to be funded.
Upgrade cost is mostly API surface. The README documents a breaking change around v4.0.0, when styled-components began forwarding refs, which removed the need for `innerRef` as a `refKey`. That is the shape of the risk: prop getter contracts and ref handling change across majors, and code that spreads props onto elements in unusual ways is the code most likely to break. Pinning the version and reading the changelog before a major bump is cheaper than discovering the change in production. The README does not document a rollback procedure, so plan your own.
Editorial conclusion
Adopt react-dropzone if you already own the upload transport and want the drop events, keyboard handling and file filtering handled for you. Do not adopt it if you expected a rendered uploader with progress bars and a queue, because the README shows no such component. Before committing, verify that your bundler resolves the ESM and CommonJS entry points declared in package.json and that your own element accepts the ref that getRootProps returns, since the README warns against setting ref yourself.
Frequently asked questions
What is react-dropzone in React?
It is a React hook, and an optional wrapper component, that creates an HTML5-compliant drag-and-drop zone for files. It returns prop getters you spread onto your own container and input elements rather than rendering a component for you.
How do I install react-dropzone?
Install it from npm with npm install react-dropzone, or with yarn add react-dropzone. The README states the package ships as ESM and CommonJS with TypeScript types included and works with modern bundlers.
How do I use react-dropzone?
Call useDropzone with an onDrop callback, then spread getRootProps() onto your container and getInputProps() onto an input element. The README notes that if you omit the input or do not bind getInputProps(), opening a file dialog will not be possible.
How do I install react-dropzone in a project?
The README gives npm install react-dropzone and yarn add react-dropzone as the two documented installation commands. There is no separate setup step beyond installing the package.
What is react-dropzone?
It is a React package for building a file drop zone, described in the README as a simple React hook to create an HTML5-compliant drag and drop zone for files. It handles the drag events and file selection, and leaves uploading and file reading to your code.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/react-dropzone-react-dropzone)