{"id":15112,"library":"formdata-polyfill","title":"HTML5 FormData Polyfill for Browsers and Node.js","description":"The `formdata-polyfill` package provides a robust, spec-compliant `FormData` implementation for both browser environments and Node.js. For browsers, it acts as a polyfill, conditionally replacing the native `FormData` implementation to ensure consistent behavior across older browsers, including patches for `XMLHttpRequest.prototype.send`, `fetch`, and `navigator.sendBeacon`. For Node.js, it offers a pure, modular, and spec-compatible `FormData` class, verified by Web Platform Tests (WPT), which integrates seamlessly with `node-fetch` and modern `fetch` implementations. The current stable version is 4.0.10, released in late 2021. While new feature development appears to have slowed since then, it remains a maintained solution for consistent `FormData` handling, particularly for environments where native support is lacking or inconsistent. A key differentiator is its `formDataToBlob` utility, adopted by projects like Deno and Undici, enabling efficient serialization of `FormData` into `Blob` objects for HTTP requests.","status":"maintenance","version":"4.0.10","language":"javascript","source_language":"en","source_url":"https://jimmywarting@github.com/jimmywarting/FormData","tags":["javascript","formdata","fetch","node-fetch","html5","browser","polyfill"],"install":[{"cmd":"npm install formdata-polyfill","lang":"bash","label":"npm"},{"cmd":"yarn add formdata-polyfill","lang":"bash","label":"yarn"},{"cmd":"pnpm add formdata-polyfill","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core dependency for Blob and File handling in Node.js environments.","package":"fetch-blob","optional":false},{"reason":"Commonly used with `formdata-polyfill` in Node.js for making network requests. While not a direct dependency, it's a primary integration target.","package":"node-fetch","optional":true}],"imports":[{"note":"For Node.js, the `FormData` class is exposed as a named export from the ESM build. The package's main entry point for CommonJS provides the browser polyfill, not the Node.js module.","wrong":"const FormData = require('formdata-polyfill');","symbol":"FormData","correct":"import { FormData } from 'formdata-polyfill/esm.min.js';"},{"note":"The `formDataToBlob` utility is a named export from the ESM build, designed for converting FormData instances into Blobs.","wrong":"import formDataToBlob from 'formdata-polyfill/esm.min.js';","symbol":"formDataToBlob","correct":"import { formDataToBlob } from 'formdata-polyfill/esm.min.js';"},{"note":"To activate the polyfill in a browser environment, simply import the package's side effects. This patches the global `FormData` and related APIs.","wrong":"import { FormData } from 'formdata-polyfill';","symbol":"Polyfill activation (browser)","correct":"import 'formdata-polyfill';"}],"quickstart":{"code":"import fetch from 'node-fetch';\nimport File from 'fetch-blob/file.js';\nimport { fileFromSync } from 'fetch-blob/from.js';\nimport { FormData, formDataToBlob } from 'formdata-polyfill/esm.min.js';\nimport { Readable } from 'node:stream';\nimport fs from 'node:fs';\n\n// Create a dummy README.md for the quickstart if it doesn't exist\nif (!fs.existsSync('./README.md')) {\n  fs.writeFileSync('./README.md', '# Quickstart Test\\nThis is a test file for the formdata-polyfill quickstart.');\n}\n\nasync function runQuickstart() {\n  console.log('--- FormData with fetch ---');\n  const filePath = './README.md';\n  const file = fileFromSync(filePath);\n  const fd = new FormData();\n\n  fd.append('file-upload-simple', new File(['abc'], 'hello-world.txt', { type: 'text/plain' }));\n  fd.append('file-upload-readme', file, 'quickstart-readme.md');\n\n  // It's also possible to append file/blob look-a-like items\n  // if you have streams coming from other destinations\n  const dummyStream = Readable.from(['part1', 'part2', 'part3']);\n  fd.append('file-upload-stream', {\n    size: 123,\n    type: 'video/mp4',\n    name: 'cat-video.mp4',\n    stream() { return dummyStream; },\n    [Symbol.toStringTag]: 'File'\n  }, 'cat-video.mp4');\n\n  try {\n    const response = await fetch('https://httpbin.org/post', { method: 'POST', body: fd });\n    const data = await response.json();\n    console.log('FormData fetch response:', data.files || data.form || data.data);\n  } catch (error) {\n    console.error('Error during FormData fetch:', error.message);\n  }\n\n  console.log('\\n--- FormData converted to Blob with fetch ---');\n  const anotherFd = new FormData();\n  anotherFd.append('text', 'Hello Blob!');\n  anotherFd.append('image', new File(['image data'], 'my-image.png', { type: 'image/png' }));\n\n  const blob = formDataToBlob(anotherFd);\n  console.log('Generated Blob:', { size: blob.size, type: blob.type });\n\n  try {\n    const response = await fetch('https://httpbin.org/post', {\n      method: 'POST',\n      body: blob,\n      headers: {\n        'Content-Type': blob.type,\n        'Content-Length': blob.size\n      }\n    });\n    const data = await response.json();\n    console.log('Blob fetch response (parts of form data might be in `data` or `json` fields for httpbin):', data.data || data.json || data);\n  } catch (error) {\n    console.error('Error during Blob fetch:', error.message);\n  }\n}\n\nrunQuickstart();","lang":"javascript","description":"This quickstart demonstrates creating `FormData` instances in Node.js, appending various data types including files and stream-like objects, and sending them via `fetch`. It also shows how to convert `FormData` to a `Blob` using `formDataToBlob` and send the resulting `Blob`."},"warnings":[{"fix":"Review existing code for explicit `FormData` instantiation or custom polyfill logic when upgrading from 2.x to 3.x+. Remove any custom `FormData` shims or polyfills, as this package now handles global replacement.","message":"Prior to version 3.x, the browser polyfill did not globally replace the native `FormData` implementation, requiring manual instantiation or explicit patching. Upgrading to 3.x and above automatically replaces the global `FormData`, simplifying usage but potentially causing conflicts if other libraries expected a specific native `FormData` instance or attempted their own patching.","severity":"breaking","affected_versions":"<3.0.0"},{"fix":"Always convert `FormData` to a `Blob` when constructing `Request` or `Response` objects: `new Request(url, { body: fd._blob ? fd._blob() : fd })`.","message":"When using the browser polyfill, direct passing of a `FormData` instance to the `body` option of `new Request()` or `new Response()` constructors is not fully supported due to limitations in patching native constructors. Developers must explicitly call `fd._blob()` on the `FormData` instance to serialize it into a `Blob` before passing it to the constructor.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Ensure your Node.js environment is updated to version `12.20.0` or higher to meet the package's engine requirements.","message":"The Node.js ESM version (`formdata-polyfill/esm.min.js`) has higher platform dependencies, specifically requiring Node.js version `12.20.0` or higher. This is due to its reliance on modern JavaScript features like classes, symbols, and private fields. Using it with older Node.js versions will result in syntax errors during module loading.","severity":"gotcha","affected_versions":"<12.20.0 (Node.js)"},{"fix":"Thoroughly test `formdata-polyfill` in environments with other polyfills or libraries that modify native browser APIs. If conflicts arise, consider loading `formdata-polyfill` early or investigating alternative `FormData` solutions.","message":"The browser polyfill deeply patches global objects and prototypes such as `XMLHttpRequest.prototype.send`, the global `fetch` function, and `navigator.sendBeacon`. This extensive patching can lead to unforeseen conflicts or unexpected behavior if other libraries or polyfills attempt to modify the same native APIs, requiring careful testing in complex front-end environments.","severity":"gotcha","affected_versions":">=3.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"For Node.js, ensure you are using ES Modules and import explicitly: `import { FormData } from 'formdata-polyfill/esm.min.js;'`","cause":"In Node.js, attempting to use `FormData` without correctly importing the ESM module, or using CommonJS `require` directly on `formdata-polyfill/esm.min.js`.","error":"ReferenceError: FormData is not defined"},{"fix":"Explicitly convert the `FormData` to a `Blob` using `fd._blob()`: `new Request(url, { method: 'post', body: fd._blob ? fd._blob() : fd })`.","cause":"Trying to pass a `FormData` instance directly to the `body` of `new Request()` or `new Response()` in a browser environment where the polyfill is active, without manually converting it to a `Blob`.","error":"TypeError: fd._blob is not a function"},{"fix":"Upgrade your Node.js environment to version `12.20.0` or higher to meet the package's engine requirements.","cause":"Running the Node.js ESM module on an unsupported Node.js version, below `12.20.0`, which lacks support for modern JavaScript features used by the package.","error":"SyntaxError: Unexpected token 'class' (or similar ESNext syntax error on module load)"}],"ecosystem":"npm"}