{"id":17274,"library":"it-multipart","title":"it-multipart: Async Iterable Multipart Parser","description":"it-multipart is a JavaScript library designed to parse HTTP multipart messages using async iterables. It provides a robust and modern approach to handling streaming data from HTTP requests, particularly useful for file uploads or complex form data. Currently at version 3.0.14, it is part of the broader `it` (InterPlanetary Stream) ecosystem, which emphasizes composable, stream-based utilities. The project demonstrates active maintenance, with frequent updates to various `it-*` packages within its monorepo, suggesting a stable and evolving codebase. Its key differentiator lies in its deep integration with JavaScript's async iterable protocol, making it highly efficient for non-blocking I/O operations and suitable for both Node.js server environments and potentially browser-side stream processing where async iterables are supported. It ships with TypeScript types, ensuring a better developer experience for TypeScript users.","status":"active","version":"3.0.14","language":"javascript","source_language":"en","source_url":"https://github.com/achingbrain/it","tags":["javascript","typescript"],"install":[{"cmd":"npm install it-multipart","lang":"bash","label":"npm"},{"cmd":"yarn add it-multipart","lang":"bash","label":"yarn"},{"cmd":"pnpm add it-multipart","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The primary `multipart` function is a default export.","wrong":"import { multipart } from 'it-multipart'","symbol":"multipart","correct":"import multipart from 'it-multipart'"},{"note":"While primarily an ESM-first library, recent updates in the 'it' monorepo (for related packages like 'it-to-buffer') indicate efforts to support CommonJS `require()` syntax for default exports. Verify compatibility in your specific environment if encountering issues.","wrong":"const { multipart } = require('it-multipart')","symbol":"multipart (CommonJS)","correct":"const multipart = require('it-multipart')"},{"note":"Import the `Part` type for explicit type annotations when working with parsed multipart segments in TypeScript.","symbol":"Part","correct":"import type { Part } from 'it-multipart'"}],"quickstart":{"code":"import http from 'http'\nimport multipart from 'it-multipart'\n\nconst server = http.createServer(async (req, res) => {\n  if (req.method === 'POST' && req.headers['content-type']) {\n    try {\n      const boundary = req.headers['content-type'].split('boundary=')[1]\n      if (!boundary) {\n        res.writeHead(400, { 'Content-Type': 'text/plain' })\n        res.end('Missing boundary in Content-Type header')\n        return\n      }\n\n      for await (const part of multipart(req, boundary)) {\n        console.log(`Received part with headers:`, part.headers)\n\n        let partContent = ''\n        // nb. part.body must be consumed before the next part is emitted\n        for await (const chunk of part.body) {\n          partContent += chunk.toString()\n        }\n        console.log(`Part name: ${part.name}, Content:`, partContent)\n      }\n\n      console.log('Finished parsing multipart message.')\n      res.writeHead(200, { 'Content-Type': 'text/plain' })\n      res.end('Multipart message parsed successfully.')\n    } catch (error) {\n      console.error('Error parsing multipart message:', error)\n      res.writeHead(500, { 'Content-Type': 'text/plain' })\n      res.end('Error parsing multipart message: ' + error.message)\n    }\n  } else {\n    res.writeHead(404, { 'Content-Type': 'text/plain' })\n    res.end('Not Found or Unsupported Method')\n  }\n})\n\nserver.listen(5001, () => {\n  console.log('Server listening on port 5001')\n})\n\n// Example usage with curl:\n// curl -X POST -H \"Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW\" -F \"field1=value1\" -F \"file1=@./package.json\" http://localhost:5001","lang":"typescript","description":"This code demonstrates how to create an HTTP server that listens for POST requests with a 'multipart/form-data' content type, parses the incoming multipart message using `it-multipart`, and logs the headers and content of each part."},"warnings":[{"fix":"Ensure a `for await...of` loop or a similar consumption mechanism processes `part.body` completely for each `part` before the outer loop proceeds to the next `part`.","message":"When iterating over multipart parts, the `part.body` async iterable for the current part MUST be fully consumed before the next part can be emitted by the `multipart` parser. Failing to consume `part.body` will lead to stalls or incomplete parsing.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"When using `multipart(req)`, ensure `req.headers['content-type']` is available and contains the boundary, or extract it manually and pass it as `multipart(req, boundary)`.","message":"The `multipart` function now expects the `boundary` string to be passed as a second argument, or inferred from the `req.headers['content-type']`. In previous versions, the boundary might have been automatically extracted or handled differently. Explicitly extracting and passing the boundary ensures correct parsing.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Embrace the async iterable pattern. Use `for await...of` loops to consume streams or leverage utilities from the `it-pipe` package for more complex stream compositions between async iterables.","message":"The `it-multipart` library is built around async iterables. Directly attempting to use it with older Node.js stream APIs (e.g., piping to traditional `Writable` streams) without proper adaptation (e.g., using `it-pipe` or manually iterating) can lead to unexpected behavior or errors.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Ensure you are using `import multipart from 'it-multipart'` in ESM modules. If using CommonJS, verify the environment's support for importing ESM default exports, or use `const multipart = require('it-multipart')` and test its functionality.","cause":"Attempting to use `require` with `it-multipart` in a strict ESM context, or an incorrect named import.","error":"TypeError: multipart is not a function or not iterable"},{"fix":"Confirm that `part.body` is fully consumed for each part within its loop, and that the upstream HTTP request stream is correctly handled and not closed before all parts are processed.","cause":"Attempting to read from `part.body` after it has been fully consumed or if the upstream stream has closed prematurely, possibly due to not consuming `part.body` for a previous part.","error":"Error: stream has ended or has no more data"}],"ecosystem":"npm","meta_description":null}