react-dropzone vs dropzone vs filepond vs blueimp-file-upload vs ng-file-upload vs fine-uploader vs uppy
File Upload Libraries for Web Development Comparison
1 Year
react-dropzonedropzonefilepondblueimp-file-uploadng-file-uploadfine-uploaderuppySimilar Packages:
What's File Upload Libraries for Web Development?

File upload libraries provide developers with tools to easily implement file upload functionality in web applications. They handle file selection, drag-and-drop support, progress tracking, and error handling, allowing for a smoother user experience. These libraries often come with customizable options and various features to suit different project requirements, making it easier to integrate file uploads into web applications without having to build the functionality from scratch.

Package Weekly Downloads Trend
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
react-dropzone4,022,04310,710567 kB595 days agoMIT
dropzone540,12718,210938 kB1573 years agoMIT
filepond127,56415,4251.18 MB132a month agoMIT
blueimp-file-upload85,12430,947-523 years agoMIT
ng-file-upload83,0387,852-3258 years agoMIT
fine-uploader24,8308,174-1227 years agoMIT
uppy18,40329,5345.48 MB1554 days agoMIT
Feature Comparison: react-dropzone vs dropzone vs filepond vs blueimp-file-upload vs ng-file-upload vs fine-uploader vs uppy

Drag-and-Drop Support

  • react-dropzone:

    React Dropzone is built specifically for React applications and provides a powerful drag-and-drop interface, allowing for easy integration and customization within React components.

  • dropzone:

    Dropzone excels in drag-and-drop functionality, providing a highly customizable interface that visually indicates where files can be dropped, along with instant previews of uploaded files.

  • filepond:

    FilePond supports drag-and-drop uploads with a smooth user experience, allowing users to drag files into the upload area while also providing visual feedback and previews.

  • blueimp-file-upload:

    Blueimp File Upload offers basic drag-and-drop support, allowing users to drag files into a designated area for upload, enhancing user experience with minimal setup.

  • ng-file-upload:

    ng-file-upload supports drag-and-drop file uploads, but its implementation is more straightforward and less visually engaging than other libraries.

  • fine-uploader:

    Fine Uploader includes drag-and-drop support but focuses more on traditional file selection methods, making it less visually appealing compared to others.

  • uppy:

    Uppy offers a modern drag-and-drop interface that is highly interactive and user-friendly, making it easy for users to upload files from various sources.

Customization Options

  • react-dropzone:

    React Dropzone allows for significant customization through props and styles, enabling developers to create a tailored upload experience that fits their application's design.

  • dropzone:

    Dropzone is highly customizable, allowing developers to modify the appearance and behavior of the upload area extensively through CSS and JavaScript options.

  • filepond:

    FilePond is designed for extensibility, providing a modular approach that allows developers to add or remove features easily, making it highly customizable for different use cases.

  • blueimp-file-upload:

    Blueimp File Upload allows for basic customization through CSS and options, but it may not be as flexible as other libraries for advanced customizations.

  • ng-file-upload:

    ng-file-upload provides basic customization options, but it is primarily designed for AngularJS applications, which may limit flexibility compared to other libraries.

  • fine-uploader:

    Fine Uploader offers extensive customization options, allowing developers to control almost every aspect of the upload process, from UI to functionality.

  • uppy:

    Uppy is extremely customizable, offering a wide range of plugins and options to modify the upload experience, making it suitable for complex applications.

File Previews

  • react-dropzone:

    React Dropzone allows for file previews, but developers need to implement the preview logic themselves, providing flexibility but requiring more effort.

  • dropzone:

    Dropzone includes built-in support for file previews, allowing users to see images and files as they are uploaded, enhancing the user experience.

  • filepond:

    FilePond excels in file previews, providing instant visual feedback for images and other file types, making it user-friendly and visually appealing.

  • blueimp-file-upload:

    Blueimp File Upload provides basic file previews, but they may require additional setup to display images or other file types effectively.

  • ng-file-upload:

    ng-file-upload offers basic file preview capabilities, but they may not be as advanced or visually appealing as those in other libraries.

  • fine-uploader:

    Fine Uploader supports file previews but may require additional configuration to display them effectively, which can be a drawback for some users.

  • uppy:

    Uppy provides rich file previews out of the box, allowing users to see images and videos as they are uploaded, enhancing the overall user experience.

Integration with Frameworks

  • react-dropzone:

    React Dropzone is built specifically for React, making it an ideal choice for React applications with a straightforward API for integration.

  • dropzone:

    Dropzone can be integrated into various frameworks, but it requires additional setup for optimal use in React or Angular applications.

  • filepond:

    FilePond is designed for modern frameworks, offering excellent integration with React, Vue, and Angular, making it a versatile choice for developers.

  • blueimp-file-upload:

    Blueimp File Upload is primarily jQuery-based, making it suitable for projects that already utilize jQuery but less ideal for modern frameworks like React or Angular.

  • ng-file-upload:

    ng-file-upload is specifically designed for AngularJS applications, providing seamless integration and support for Angular's features.

  • fine-uploader:

    Fine Uploader can be integrated into any web application but may require more effort to work seamlessly with frameworks like React or Angular.

  • uppy:

    Uppy is framework-agnostic and can be easily integrated into any web application, providing a flexible solution for developers.

Error Handling and Feedback

  • react-dropzone:

    React Dropzone allows developers to implement custom error handling and feedback, providing flexibility but requiring more effort to create a seamless user experience.

  • dropzone:

    Dropzone includes built-in error handling and user feedback, providing clear messages for failed uploads and other issues, enhancing usability.

  • filepond:

    FilePond offers robust error handling and feedback options, allowing developers to customize messages and responses for various upload scenarios.

  • blueimp-file-upload:

    Blueimp File Upload provides basic error handling and feedback mechanisms, but they may require additional customization for a polished experience.

  • ng-file-upload:

    ng-file-upload provides basic error handling and feedback, but it may not be as comprehensive as other libraries, requiring additional work for a complete solution.

  • fine-uploader:

    Fine Uploader excels in error handling, providing detailed feedback and retry options for failed uploads, making it suitable for applications that require reliability.

  • uppy:

    Uppy includes advanced error handling and user feedback mechanisms, allowing for a smooth and responsive upload experience, even in case of failures.

How to Choose: react-dropzone vs dropzone vs filepond vs blueimp-file-upload vs ng-file-upload vs fine-uploader vs uppy
  • react-dropzone:

    Choose React Dropzone if you are building a React application and need a simple yet powerful drag-and-drop file upload component. It provides a clean API and is easy to integrate with other React components, making it suitable for projects that prioritize React's component-based architecture.

  • dropzone:

    Select Dropzone if you want a highly customizable drag-and-drop file upload library that provides a simple API and built-in previews. It's perfect for applications that require a modern look and feel with minimal setup, as well as for developers who want to easily style the upload interface.

  • filepond:

    Opt for FilePond if you need a flexible and extensible file upload library that supports image previews, file validation, and asynchronous uploads. Its modular architecture allows for easy customization and integration with various frameworks, making it suitable for complex applications that require advanced features.

  • blueimp-file-upload:

    Choose Blueimp File Upload if you need a simple, jQuery-based solution that supports multiple file uploads, drag-and-drop functionality, and progress bars. It's ideal for projects that already use jQuery and require a straightforward implementation without extensive customization.

  • ng-file-upload:

    Select ng-file-upload if you are working with AngularJS and need a library that integrates seamlessly with Angular's scope and promises. It's ideal for AngularJS applications that require a straightforward way to handle file uploads with built-in support for progress tracking and cancellation.

  • fine-uploader:

    Choose Fine Uploader if you require a robust solution with extensive features such as chunked uploads, retry capabilities, and a wide range of customization options. It's suitable for applications that need fine-grained control over the upload process and error handling.

  • uppy:

    Opt for Uppy if you want a modern, modular file uploader that supports multiple sources (like Google Drive and Dropbox) and provides a rich user interface. It's great for applications that require a versatile upload solution with a focus on user experience and extensibility.

README for react-dropzone

react-dropzone logo

react-dropzone

npm Tests codecov Open Collective Backers Open Collective Sponsors Gitpod Contributor Covenant

Simple React hook to create a HTML5-compliant drag'n'drop zone for files.

Documentation and examples at https://react-dropzone.js.org. Source code at https://github.com/react-dropzone/react-dropzone/.

Installation

Install it from npm and include it in your React build process (using Webpack, Browserify, etc).

npm install --save react-dropzone

or:

yarn add react-dropzone

Usage

You can either use the hook:

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>
  )
}

Or the wrapper component for the hook:

import React from 'react'
import Dropzone from 'react-dropzone'

<Dropzone onDrop={acceptedFiles => console.log(acceptedFiles)}>
  {({getRootProps, getInputProps}) => (
    <section>
      <div {...getRootProps()}>
        <input {...getInputProps()} />
        <p>Drag 'n' drop some files here, or click to select files</p>
      </div>
    </section>
  )}
</Dropzone>

If you want to access file contents you have to use the FileReader API:

import React, {useCallback} from 'react'
import {useDropzone} from 'react-dropzone'

function MyDropzone() {
  const onDrop = useCallback((acceptedFiles) => {
    acceptedFiles.forEach((file) => {
      const reader = new FileReader()

      reader.onabort = () => console.log('file reading was aborted')
      reader.onerror = () => console.log('file reading has failed')
      reader.onload = () => {
      // Do whatever you want with the file contents
        const binaryStr = reader.result
        console.log(binaryStr)
      }
      reader.readAsArrayBuffer(file)
    })
    
  }, [])
  const {getRootProps, getInputProps} = useDropzone({onDrop})

  return (
    <div {...getRootProps()}>
      <input {...getInputProps()} />
      <p>Drag 'n' drop some files here, or click to select files</p>
    </div>
  )
}

Dropzone Props Getters

The dropzone property getters are just two functions that return objects with properties which you need to use to create the drag 'n' drop zone. The root properties can be applied to whatever element you want, whereas the input properties must be applied to an <input>:

import React from 'react'
import {useDropzone} from 'react-dropzone'

function MyDropzone() {
  const {getRootProps, getInputProps} = useDropzone()

  return (
    <div {...getRootProps()}>
      <input {...getInputProps()} />
      <p>Drag 'n' drop some files here, or click to select files</p>
    </div>
  )
}

Note that whatever other props you want to add to the element where the props from getRootProps() are set, you should always pass them through that function rather than applying them on the element itself. This is in order to avoid your props being overridden (or overriding the props returned by getRootProps()):

<div
  {...getRootProps({
    onClick: event => console.log(event),
    role: 'button',
    'aria-label': 'drag and drop area',
    ...
  })}
/>

In the example above, the provided {onClick} handler will be invoked before the internal one, therefore, internal callbacks can be prevented by simply using stopPropagation. See Events for more examples.

Important: if you omit rendering an <input> and/or binding the props from getInputProps(), opening a file dialog will not be possible.

Refs

Both getRootProps and getInputProps accept a custom refKey (defaults to ref) as one of the attributes passed down in the parameter.

This can be useful when the element you're trying to apply the props from either one of those fns does not expose a reference to the element, e.g:

import React from 'react'
import {useDropzone} from 'react-dropzone'
// NOTE: After v4.0.0, styled components exposes a ref using forwardRef,
// therefore, no need for using innerRef as refKey
import styled from 'styled-components'

const StyledDiv = styled.div`
  // Some styling here
`
function Example() {
  const {getRootProps, getInputProps} = useDropzone()
  <StyledDiv {...getRootProps({ refKey: 'innerRef' })}>
    <input {...getInputProps()} />
    <p>Drag 'n' drop some files here, or click to select files</p>
  </StyledDiv>
}

If you're working with Material UI v4 and would like to apply the root props on some component that does not expose a ref, use RootRef:

import React from 'react'
import {useDropzone} from 'react-dropzone'
import RootRef from '@material-ui/core/RootRef'

function PaperDropzone() {
  const {getRootProps, getInputProps} = useDropzone()
  const {ref, ...rootProps} = getRootProps()

  <RootRef rootRef={ref}>
    <Paper {...rootProps}>
      <input {...getInputProps()} />
      <p>Drag 'n' drop some files here, or click to select files</p>
    </Paper>
  </RootRef>
}

IMPORTANT: do not set the ref prop on the elements where getRootProps()/getInputProps() props are set, instead, get the refs from the hook itself:

import React from 'react'
import {useDropzone} from 'react-dropzone'

function Refs() {
  const {
    getRootProps,
    getInputProps,
    rootRef, // Ref to the `<div>`
    inputRef // Ref to the `<input>`
  } = useDropzone()
  <div {...getRootProps()}>
    <input {...getInputProps()} />
    <p>Drag 'n' drop some files here, or click to select files</p>
  </div>
}

If you're using the <Dropzone> component, though, you can set the ref prop on the component itself which will expose the {open} prop that can be used to open the file dialog programmatically:

import React, {createRef} from 'react'
import Dropzone from 'react-dropzone'

const dropzoneRef = createRef()

<Dropzone ref={dropzoneRef}>
  {({getRootProps, getInputProps}) => (
    <div {...getRootProps()}>
      <input {...getInputProps()} />
      <p>Drag 'n' drop some files here, or click to select files</p>
    </div>
  )}
</Dropzone>

dropzoneRef.open()

Testing

react-dropzone makes some of its drag 'n' drop callbacks asynchronous to enable promise based getFilesFromEvent() functions. In order to test components that use this library, you need to use the react-testing-library:

import React from 'react'
import Dropzone from 'react-dropzone'
import {act, fireEvent, render} from '@testing-library/react'

test('invoke onDragEnter when dragenter event occurs', async () => {
  const file = new File([
    JSON.stringify({ping: true})
  ], 'ping.json', { type: 'application/json' })
  const data = mockData([file])
  const onDragEnter = jest.fn()

  const ui = (
    <Dropzone onDragEnter={onDragEnter}>
      {({ getRootProps, getInputProps }) => (
        <div {...getRootProps()}>
          <input {...getInputProps()} />
        </div>
      )}
    </Dropzone>
  )
  const { container } = render(ui)

  await act(
    () => fireEvent.dragEnter(
      container.querySelector('div'),
      data,
    )
  );
  expect(onDragEnter).toHaveBeenCalled()
})

function mockData(files) {
  return {
    dataTransfer: {
      files,
      items: files.map(file => ({
        kind: 'file',
        type: file.type,
        getAsFile: () => file
      })),
      types: ['Files']
    }
  }
}

NOTE: using Enzyme for testing is not supported at the moment, see #2011.

More examples for this can be found in react-dropzone's own test suites.

Caveats

Required React Version

React 16.8 or above is required because we use hooks (the lib itself is a hook).

File Paths

Files returned by the hook or passed as arg to the onDrop cb won't have the properties path or fullPath. For more inf check this SO question and this issue.

Not a File Uploader

This lib is not a file uploader; as such, it does not process files or provide any way to make HTTP requests to some server; if you're looking for that, checkout filepond or uppy.io.

Using <label> as Root

If you use <label> as the root element, the file dialog will be opened twice; see #1107 why. To avoid this, use noClick:

import React, {useCallback} from 'react'
import {useDropzone} from 'react-dropzone'

function MyDropzone() {
  const {getRootProps, getInputProps} = useDropzone({noClick: true})

  return (
    <label {...getRootProps()}>
      <input {...getInputProps()} />
    </label>
  )
}

Using open() on Click

If you bind a click event on an inner element and use open(), it will trigger a click on the root element too, resulting in the file dialog opening twice. To prevent this, use the noClick on the root:

import React, {useCallback} from 'react'
import {useDropzone} from 'react-dropzone'

function MyDropzone() {
  const {getRootProps, getInputProps, open} = useDropzone({noClick: true})

  return (
    <div {...getRootProps()}>
      <input {...getInputProps()} />
      <button type="button" onClick={open}>
        Open
      </button>
    </div>
  )
}

File Dialog Cancel Callback

The onFileDialogCancel() cb is unstable in most browsers, meaning, there's a good chance of it being triggered even though you have selected files.

We rely on using a timeout of 300ms after the window is focused (the window onfocus event is triggered when the file select dialog is closed) to check if any files were selected and trigger onFileDialogCancel if none were selected.

As one can imagine, this doesn't really work if there's a lot of files or large files as by the time we trigger the check, the browser is still processing the files and no onchange events are triggered yet on the input. Check #1031 for more info.

Fortunately, there's the File System Access API, which is currently a working draft and some browsers support it (see browser compatibility), that provides a reliable way to prompt the user for file selection and capture cancellation.

Also keep in mind that the FS access API can only be used in secure contexts.

NOTE You can enable using the FS access API with the useFsAccessApi property: useDropzone({useFsAccessApi: true}).

File System Access API

When setting useFsAccessApi to true, you're switching to the File System API (see the file system access RFC).

What this essentially does is that it will use the showOpenFilePicker method to open the file picker window so that the user can select files.

In contrast, the traditional way (when the useFsAccessApi is not set to true or not specified) uses an <input type="file"> (see docs) on which a click event is triggered.

With the use of the file system access API enabled, there's a couple of caveats to keep in mind:

  1. The users will not be able to select directories
  2. It requires the app to run in a secure context
  3. In Electron, the path may not be set (see #1249)

Supported Browsers

We use browserslist config to state the browser support for this lib, so check it out on browserslist.dev.

Need image editing?

React Dropzone integrates perfectly with Pintura Image Editor, creating a modern image editing experience. Pintura supports crop aspect ratios, resizing, rotating, cropping, annotating, filtering, and much more.

Checkout the Pintura integration example.

Support

Backers

Support us with a monthly donation and help us continue our activities. [Become a backer]

Sponsors

Become a sponsor and get your logo on our README on Github with a link to your site. [Become a sponsor]

Hosting

react-dropzone.js.org hosting provided by netlify.

Contribute

Checkout the organization CONTRIBUTING.md.

License

MIT