DEV Community

Cover image for Multipart form data isn't as mysterious as it looks
mksunny1
mksunny1

Posted on

Multipart form data isn't as mysterious as it looks

If you've ever uploaded a file from a browser, you've probably encountered multipart/form-data. The name sounds more complicated than it really is. A browser submitting a form might send something conceptually like this:

--boundary
Content-Disposition: form-data; name="name"

Seyi
--boundary
Content-Disposition: form-data; name="avatar"; filename="photo.jpg"
Content-Type: image/jpeg

<binary JPEG data>
--boundary
Content-Disposition: form-data; name="description"

A photograph
--boundary--
Enter fullscreen mode Exit fullscreen mode

That's multipart.

Each part is simply one piece of the form: a text field, a file, or another submitted value.

The boundary tells the server where one part ends and the next begins.

Once I looked at it this way, I started wondering why handling multipart requests in a Node application often means bringing in a fairly substantial abstraction.

There are very good and mature libraries for this. busboy, formidable, multer, and others solve much broader problems and have been used successfully for years.

But for an application that already works directly with Node's HTTP streams, I wanted something smaller.

So I built node-multipart.

It works directly with Node's IncomingMessage and exposes the multipart stream as a sequence of parts:

const part = await multipart.nextData()
const bytes = await multipart.pipeNextTo(destination)
const value = await multipart.readNextValue()
Enter fullscreen mode Exit fullscreen mode

The parser handles the protocol mechanics:

  • Finding multipart boundaries
  • Parsing part headers
  • Handling boundaries split across network chunks
  • Preserving binary data
  • Streaming part contents
  • Respecting writable-stream backpressure
  • Per-part size limits
  • Header size limits

The application handles everything application-specific:

  • What fields are allowed
  • Where files are stored
  • What filenames to use
  • File validation
  • Authorization
  • Overall request limits
  • Part-count limits

There are no runtime dependencies, no temporary files, and no requirement to buffer an entire upload.

The goal isn't to replace the mature multipart ecosystem.

It's simply to make the underlying operation visible and provide a small Node-native primitive for applications that don't need a larger upload framework.

node-multipart is now at v1.1.2.

GitHub: mksunny1/node-multipart
npm: node-multipart

If you've ever looked at multipart/form-data and thought "surely this doesn't need to be this complicated", this is basically the experiment that came out of that thought.

Top comments (0)