busboy vs formidable vs multer vs express-fileupload vs connect-busboy
Node.js File Upload Libraries Comparison
1 Year
busboyformidablemulterexpress-fileuploadconnect-busboySimilar Packages:
What's Node.js File Upload Libraries?

These libraries are designed to handle file uploads in Node.js applications. They provide various functionalities to parse incoming multipart/form-data requests, manage file streams, and facilitate the handling of uploaded files. Each library has its own approach and features, making them suitable for different use cases and preferences in web development.

Package Weekly Downloads Trend
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
busboy15,667,4842,898124 kB35--
formidable11,301,3977,099203 kB514 months agoMIT
multer6,466,98111,70527.6 kB269-MIT
express-fileupload440,2061,540116 kB227 months agoMIT
connect-busboy40,7001554.57 kB0--
Feature Comparison: busboy vs formidable vs multer vs express-fileupload vs connect-busboy

Ease of Use

  • busboy:

    Busboy is a low-level library that requires more manual handling of streams and file data, which can be challenging for beginners but offers flexibility for advanced users.

  • formidable:

    Formidable provides a comprehensive API that simplifies file uploads while offering advanced features, making it relatively easy to use for developers familiar with Node.js.

  • multer:

    Multer is designed specifically for Express and is straightforward to implement, with clear documentation and examples that make it accessible for developers.

  • express-fileupload:

    Express-FileUpload is very user-friendly, allowing developers to handle file uploads with minimal setup and clear API methods for accessing files.

  • connect-busboy:

    Connect-Busboy is easy to integrate with existing Connect applications, providing a straightforward way to handle file uploads without much configuration.

Streaming Support

  • busboy:

    Busboy excels in streaming file uploads, allowing files to be processed as they are being uploaded, which is efficient for large files and reduces memory usage.

  • formidable:

    Formidable supports streaming uploads and can handle large files efficiently by processing them in chunks, making it suitable for applications dealing with significant file sizes.

  • multer:

    Multer supports streaming uploads but primarily buffers files in memory or on disk, depending on the configuration, which can be a limitation for very large files.

  • express-fileupload:

    Express-FileUpload does not natively support streaming, as it buffers files in memory, which may not be ideal for large uploads.

  • connect-busboy:

    Connect-Busboy leverages Busboy's streaming capabilities, providing efficient file handling in a middleware format for Connect applications.

File Size Limitations

  • busboy:

    Busboy does not impose file size limits by default, allowing developers to implement their own checks according to application needs.

  • formidable:

    Formidable allows developers to set file size limits and provides error handling for exceeding those limits, making it robust for file management.

  • multer:

    Multer allows setting limits on file sizes and number of files uploaded, providing built-in error handling for exceeding these limits.

  • express-fileupload:

    Express-FileUpload allows setting file size limits easily through options, providing a straightforward way to control upload sizes.

  • connect-busboy:

    Connect-Busboy inherits Busboy's flexibility regarding file size limits, enabling custom implementations for handling large files.

File Management Features

  • busboy:

    Busboy focuses on parsing and streaming files but does not provide built-in file management features like renaming or moving files after upload.

  • formidable:

    Formidable offers advanced file management features, including file renaming, progress tracking, and automatic parsing, making it suitable for complex applications.

  • multer:

    Multer provides flexible storage options, allowing developers to define custom storage engines and manage file uploads effectively, including renaming and organizing files.

  • express-fileupload:

    Express-FileUpload provides basic file management features, allowing easy access to uploaded files but lacks advanced management options like renaming or organizing files.

  • connect-busboy:

    Connect-Busboy inherits Busboy's minimalistic approach, focusing on parsing rather than file management, requiring additional handling for file storage.

Community and Support

  • busboy:

    Busboy has a smaller community compared to other libraries, which may result in limited support and resources for troubleshooting.

  • formidable:

    Formidable has been around for a while and has a solid community, providing ample resources, documentation, and support for developers.

  • multer:

    Multer is widely used in the Express community, with extensive documentation and a large user base, ensuring robust support and resources for developers.

  • express-fileupload:

    Express-FileUpload has a growing community and good documentation, making it easier to find support and examples for common use cases.

  • connect-busboy:

    Connect-Busboy is less popular but benefits from the Busboy community, offering some support through shared resources and documentation.

How to Choose: busboy vs formidable vs multer vs express-fileupload vs connect-busboy
  • busboy:

    Choose Busboy if you need a lightweight and efficient streaming parser for handling file uploads without any additional features. It is ideal for applications that require low-level control over the file upload process and can handle streams directly.

  • formidable:

    Use Formidable if you need a robust solution that can handle file uploads with additional features like file renaming, progress tracking, and automatic file parsing. It is suitable for applications that require more control and flexibility in managing uploaded files.

  • multer:

    Choose Multer if you are looking for a powerful middleware specifically designed for handling multipart/form-data in Express applications. It offers a variety of storage options, including memory storage and disk storage, and is highly configurable for different use cases.

  • express-fileupload:

    Select Express-FileUpload if you prefer a simple and easy-to-use middleware for handling file uploads in Express applications. It supports both single and multiple file uploads and provides a straightforward API for accessing uploaded files.

  • connect-busboy:

    Opt for Connect-Busboy if you are using the Connect middleware framework and want a seamless integration for file uploads. It provides a simple way to handle multipart forms in a Connect-based application, leveraging Busboy's capabilities.

README for busboy

Description

A node.js module for parsing incoming HTML form data.

Changes (breaking or otherwise) in v1.0.0 can be found here.

Requirements

Install

npm install busboy

Examples

  • Parsing (multipart) with default options:
const http = require('http');

const busboy = require('busboy');

http.createServer((req, res) => {
  if (req.method === 'POST') {
    console.log('POST request');
    const bb = busboy({ headers: req.headers });
    bb.on('file', (name, file, info) => {
      const { filename, encoding, mimeType } = info;
      console.log(
        `File [${name}]: filename: %j, encoding: %j, mimeType: %j`,
        filename,
        encoding,
        mimeType
      );
      file.on('data', (data) => {
        console.log(`File [${name}] got ${data.length} bytes`);
      }).on('close', () => {
        console.log(`File [${name}] done`);
      });
    });
    bb.on('field', (name, val, info) => {
      console.log(`Field [${name}]: value: %j`, val);
    });
    bb.on('close', () => {
      console.log('Done parsing form!');
      res.writeHead(303, { Connection: 'close', Location: '/' });
      res.end();
    });
    req.pipe(bb);
  } else if (req.method === 'GET') {
    res.writeHead(200, { Connection: 'close' });
    res.end(`
      <html>
        <head></head>
        <body>
          <form method="POST" enctype="multipart/form-data">
            <input type="file" name="filefield"><br />
            <input type="text" name="textfield"><br />
            <input type="submit">
          </form>
        </body>
      </html>
    `);
  }
}).listen(8000, () => {
  console.log('Listening for requests');
});

// Example output:
//
// Listening for requests
//   < ... form submitted ... >
// POST request
// File [filefield]: filename: "logo.jpg", encoding: "binary", mime: "image/jpeg"
// File [filefield] got 11912 bytes
// Field [textfield]: value: "testing! :-)"
// File [filefield] done
// Done parsing form!
  • Save all incoming files to disk:
const { randomFillSync } = require('crypto');
const fs = require('fs');
const http = require('http');
const os = require('os');
const path = require('path');

const busboy = require('busboy');

const random = (() => {
  const buf = Buffer.alloc(16);
  return () => randomFillSync(buf).toString('hex');
})();

http.createServer((req, res) => {
  if (req.method === 'POST') {
    const bb = busboy({ headers: req.headers });
    bb.on('file', (name, file, info) => {
      const saveTo = path.join(os.tmpdir(), `busboy-upload-${random()}`);
      file.pipe(fs.createWriteStream(saveTo));
    });
    bb.on('close', () => {
      res.writeHead(200, { 'Connection': 'close' });
      res.end(`That's all folks!`);
    });
    req.pipe(bb);
    return;
  }
  res.writeHead(404);
  res.end();
}).listen(8000, () => {
  console.log('Listening for requests');
});

API

Exports

busboy exports a single function:

( function )(< object >config) - Creates and returns a new Writable form parser stream.

  • Valid config properties:

    • headers - object - These are the HTTP headers of the incoming request, which are used by individual parsers.

    • highWaterMark - integer - highWaterMark to use for the parser stream. Default: node's stream.Writable default.

    • fileHwm - integer - highWaterMark to use for individual file streams. Default: node's stream.Readable default.

    • defCharset - string - Default character set to use when one isn't defined. Default: 'utf8'.

    • defParamCharset - string - For multipart forms, the default character set to use for values of part header parameters (e.g. filename) that are not extended parameters (that contain an explicit charset). Default: 'latin1'.

    • preservePath - boolean - If paths in filenames from file parts in a 'multipart/form-data' request shall be preserved. Default: false.

    • limits - object - Various limits on incoming data. Valid properties are:

      • fieldNameSize - integer - Max field name size (in bytes). Default: 100.

      • fieldSize - integer - Max field value size (in bytes). Default: 1048576 (1MB).

      • fields - integer - Max number of non-file fields. Default: Infinity.

      • fileSize - integer - For multipart forms, the max file size (in bytes). Default: Infinity.

      • files - integer - For multipart forms, the max number of file fields. Default: Infinity.

      • parts - integer - For multipart forms, the max number of parts (fields + files). Default: Infinity.

      • headerPairs - integer - For multipart forms, the max number of header key-value pairs to parse. Default: 2000 (same as node's http module).

This function can throw exceptions if there is something wrong with the values in config. For example, if the Content-Type in headers is missing entirely, is not a supported type, or is missing the boundary for 'multipart/form-data' requests.

(Special) Parser stream events

  • file(< string >name, < Readable >stream, < object >info) - Emitted for each new file found. name contains the form field name. stream is a Readable stream containing the file's data. No transformations/conversions (e.g. base64 to raw binary) are done on the file's data. info contains the following properties:

    • filename - string - If supplied, this contains the file's filename. WARNING: You should almost never use this value as-is (especially if you are using preservePath: true in your config) as it could contain malicious input. You are better off generating your own (safe) filenames, or at the very least using a hash of the filename.

    • encoding - string - The file's 'Content-Transfer-Encoding' value.

    • mimeType - string - The file's 'Content-Type' value.

    Note: If you listen for this event, you should always consume the stream whether you care about its contents or not (you can simply do stream.resume(); if you want to discard/skip the contents), otherwise the 'finish'/'close' event will never fire on the busboy parser stream. However, if you aren't accepting files, you can either simply not listen for the 'file' event at all or set limits.files to 0, and any/all files will be automatically skipped (these skipped files will still count towards any configured limits.files and limits.parts limits though).

    Note: If a configured limits.fileSize limit was reached for a file, stream will both have a boolean property truncated set to true (best checked at the end of the stream) and emit a 'limit' event to notify you when this happens.

  • field(< string >name, < string >value, < object >info) - Emitted for each new non-file field found. name contains the form field name. value contains the string value of the field. info contains the following properties:

    • nameTruncated - boolean - Whether name was truncated or not (due to a configured limits.fieldNameSize limit)

    • valueTruncated - boolean - Whether value was truncated or not (due to a configured limits.fieldSize limit)

    • encoding - string - The field's 'Content-Transfer-Encoding' value.

    • mimeType - string - The field's 'Content-Type' value.

  • partsLimit() - Emitted when the configured limits.parts limit has been reached. No more 'file' or 'field' events will be emitted.

  • filesLimit() - Emitted when the configured limits.files limit has been reached. No more 'file' events will be emitted.

  • fieldsLimit() - Emitted when the configured limits.fields limit has been reached. No more 'field' events will be emitted.