Skip to content

Replacements for form-data ​

FormData is built into Node.js and all modern browsers, and fetch sends it without any extra packages.

FormData (native, since Node.js 18.0.0) ​

The native FormData works with fetch, which sets the Content-Type header, including the boundary, for you. Don't set that header yourself.

js
import FormData from 'form-data'

const form = new FormData()
form.append('name', 'Jane')

await fetch('https://example.com/upload', {
  method: 'POST',
  headers: form.getHeaders(), 
  body: form
})

Buffers ​

Wrap the data in a Blob, and pass the filename as the third argument. Set the content type on the Blob, since it isn't guessed from the filename.

js
form.append('image', buffer, { filename: 'photo.png', contentType: 'image/png' }) 
form.append('image', new Blob([buffer], { type: 'image/png' }), 'photo.png') 

Files ​

Use fs.openAsBlob (since Node.js 19.8.0) instead of a read stream. Unlike form-data, the filename and content type aren't taken from the path, so pass them yourself.

js
import fs from 'node:fs'
import { openAsBlob } from 'node:fs'

form.append('report', fs.createReadStream('./report.pdf')) 
form.append('report', await openAsBlob('./report.pdf', { type: 'application/pdf' }), 'report.pdf') 

For other streams, read them into a Blob first, for example with node:stream/consumers:

js
import { buffer } from 'node:stream/consumers'

form.append('data', new Blob([await buffer(stream)]), 'data.bin')

submit() ​

Use fetch instead.

js
form.submit('https://example.com/upload', (err, res) => { 
  // ...
}) 
const res = await fetch('https://example.com/upload', { method: 'POST', body: form }) 

getHeaders(), getBuffer() and getLength() ​

If you need the encoded body without fetch, for example to send it with node:http, encode the form with a Response. Its Content-Type header includes the generated boundary.

js
const headers = form.getHeaders() 
const body = form.getBuffer() 
const encoded = new Response(form) 
const headers = { 'content-type': encoded.headers.get('content-type') } 
const body = Buffer.from(await encoded.arrayBuffer()) 

http.request(url, { method: 'POST', headers: { ...headers, 'content-length': body.length } }).end(body)

The native FormData always generates its own boundary, so there is no equivalent to setBoundary().

Released under the MIT License. (2b9c3f42)