{"id":12939,"library":"busboy","title":"Busboy: HTML Form Data Parser for Node.js","description":"Busboy is a high-performance, streaming parser for incoming HTML form data in Node.js, specifically designed to handle `multipart/form-data` and `application/x-www-form-urlencoded` request bodies. As of version 1.6.0, it provides a lightweight and memory-efficient solution for processing file uploads and form fields by emitting events as data streams in, rather than buffering the entire request. Its event-driven API grants developers fine-grained control over how incoming data is managed, making it suitable for integration with various storage solutions or processing pipelines. While a precise release cadence isn't publicly defined, the project appears actively maintained. Busboy differentiates itself by focusing purely on parsing the raw input stream without making assumptions about how the parsed data should be stored or handled, leaving those decisions entirely to the application developer. It requires Node.js v10.16.0 or newer.","status":"active","version":"1.6.0","language":"javascript","source_language":"en","source_url":"ssh://git@github.com/mscdex/busboy","tags":["javascript","uploads","forms","multipart","form-data"],"install":[{"cmd":"npm install busboy","lang":"bash","label":"npm"},{"cmd":"yarn add busboy","lang":"bash","label":"yarn"},{"cmd":"pnpm add busboy","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Busboy is primarily a CommonJS module. Direct ESM `import` statements may not work as expected without a transpiler or ESM wrapper due to its `module.exports = function` structure.","wrong":"import busboy from 'busboy';","symbol":"busboy (function)","correct":"const busboy = require('busboy');"},{"note":"Since v1.0.0, `busboy` is a function that returns a Writable stream, not a constructor. Attempting to use `new` will result in a TypeError.","wrong":"const bb = new busboy({ headers: req.headers });","symbol":"Busboy instance (returned stream)","correct":"const bb = busboy({ headers: req.headers });"},{"note":"Even if an ESM loader were used for CJS, `busboy` exports a default function, not named exports. Named imports will fail.","wrong":"import { busboy } from 'busboy';","symbol":"Named import (for CJS module)","correct":"const busboy = require('busboy');"}],"quickstart":{"code":"const http = require('http');\nconst busboy = require('busboy');\n\nconst port = process.env.PORT ?? 8000;\n\nhttp.createServer((req, res) => {\n  if (req.method === 'POST') {\n    console.log('POST request received');\n    const bb = busboy({ headers: req.headers });\n    bb.on('file', (name, file, info) => {\n      const { filename, encoding, mimeType } = info;\n      console.log(\n        `File [${name}]: filename: %j, encoding: %j, mimeType: %j`,\n        filename, encoding, mimeType\n      );\n      file.on('data', (data) => {\n        console.log(`File [${name}] got ${data.length} bytes`);\n      }).on('close', () => {\n        console.log(`File [${name}] done`);\n      });\n    });\n    bb.on('field', (name, val, info) => {\n      console.log(`Field [${name}]: value: %j`, val);\n    });\n    bb.on('close', () => {\n      console.log('Done parsing form!');\n      res.writeHead(303, { Connection: 'close', Location: '/' });\n      res.end();\n    });\n    req.pipe(bb);\n  } else if (req.method === 'GET') {\n    res.writeHead(200, { 'Content-Type': 'text/html', Connection: 'close' });\n    res.end(`\n      <html>\n        <head><title>Upload Form</title></head>\n        <body>\n          <form method=\"POST\" enctype=\"multipart/form-data\">\n            <input type=\"file\" name=\"filefield\"><br />\n            <input type=\"text\" name=\"textfield\"><br />\n            <input type=\"submit\" value=\"Upload\">\n          </form>\n        </body>\n      </html>\n    `);\n  }\n}).listen(port, () => {\n  console.log(`Listening for requests on http://localhost:${port}`);\n});","lang":"javascript","description":"This example sets up a basic HTTP server that uses Busboy to parse multipart/form-data POST requests. It demonstrates how to listen for 'file' and 'field' events to process incoming file uploads and regular form fields, logging their details and data lengths."},"warnings":[{"fix":"Migrate `new Busboy(...)` calls to `busboy(...)`. Review event signatures for 'file' and 'field' events, as their arguments were consolidated into an `info` object. Additionally, the default for `preservePath` changed to `false` for multipart files.","message":"Busboy v1.0.0 introduced significant breaking changes, primarily altering its API surface. The main export changed from a constructor (`new Busboy()`) to a function (`busboy()`) that returns a parser stream.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"For `file` events, instead of `(name, file, filename, encoding, mimetype)`, use `(name, file, info)` and access properties like `info.filename`. For `field` events, instead of `(name, val, fieldnameTruncated, valTruncated, encoding, mimetype)`, use `(name, val, info)` and access properties like `info.nameTruncated`.","message":"The `file` and `field` event signatures were changed in v1.0.0 to consolidate metadata into an `info` object. Direct access to arguments like `filename` or `fieldnameTruncated` as separate parameters is no longer supported.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Always attach 'data' and 'end'/'close' listeners to the `file` stream, or pipe it to a destination (e.g., `fs.createWriteStream`). If a file stream is not consumed, ensure `file.resume()` is called to prevent the parser from stalling.","message":"Busboy is a streaming parser, meaning it does not buffer entire files or fields by default. This requires careful handling of the 'file' stream to prevent backpressure issues or resource leaks if the stream is not consumed or piped.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Always sanitize `info.filename` before using it to construct a file path. Use a library like `path.basename()` or implement a robust sanitation method to ensure the path does not escape the intended directory. For example, `path.join(uploadDir, path.basename(info.filename))`.","message":"When saving uploaded files to disk, directly using `info.filename` (from the `file` event) can expose your server to path traversal vulnerabilities if not properly sanitized.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Configure `limits` in the Busboy options, such as `limits: { fileSize: 10 * 1024 * 1024, files: 5, fields: 10 }` to restrict maximum file size, number of files, and number of fields, respectively. Also, implement timeouts for inactive connections.","message":"Busboy does not enforce limits on file sizes or the number of fields/files by default, which can lead to Denial of Service (DoS) attacks through memory exhaustion if not configured.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Remove the `new` keyword: `const bb = busboy({ headers: req.headers });`","cause":"Attempting to instantiate Busboy using `new busboy()` instead of calling it as a function.","error":"TypeError: busboy is not a constructor"},{"fix":"Ensure the package is installed in your project: `npm install busboy` or `yarn add busboy`.","cause":"The 'busboy' package is not installed or the Node.js runtime cannot locate it.","error":"Error: Cannot find module 'busboy'"},{"fix":"Use the CommonJS `require` syntax: `const busboy = require('busboy');`","cause":"Attempting to use ESM named import syntax for a CommonJS module that exports a default function.","error":"SyntaxError: Named export 'busboy' not found (import { busboy } from 'busboy')"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":""}