Sign Up for Free

RunKit +

Try any Node.js package right in your browser

This is a playground to test code. It runs a full Node.js environment and already has all of npm’s 400,000 packages pre-installed, including fastify-multipart with all npm packages installed. Try it out:

var fastifyMultipart = require("fastify-multipart")

This service is provided by RunKit and is not affiliated with npm, Inc or the package authors.

fastify-multipart v1.0.2

Multipart plugin for Fastify


Greenkeeper badge

js-standard-style Build Status

Fastify plugin to parse the multipart content-type.

Under the hood it uses busboy.


npm i fastify-multipart --save


const fastify = require('fastify')()
const concat = require('concat-stream')
const fs = require('fs')
const pump = require('pump')

fastify.register(require('fastify-multipart'))'/', function (req, reply) {
  const mp = req.multipart(handler, function (err) {
    console.log('upload completed')

  // mp is an instance of

  mp.on('field', function (key, value) {
    console.log('form-data', key, value)

  function handler (field, file, filename, encoding, mimetype) {
    // to accumulate the file in memory! Be careful!
    // file.pipe(concat(function (buf) {
    //   console.log('received', filename, 'size', buf.length)
    // }))
    // or

    pump(file, fs.createWriteStream('a-destination'))

    // be careful of permission issues on disk and not overwrite
    // sensitive files that could cause security risks

fastify.listen(3000, err => {
  if (err) throw err
  console.log(`server listening on ${fastify.server.address().port}`)

You can also pass optional arguments to busboy when registering with fastify. This is useful for setting limits on the content that can be uploaded. A full list of available options can be found in the busboy documentation.

fastify.register(require('fastify-multipart'), {
  limits: {
    fieldNameSize: 100, // Max field name size in bytes
    fieldSize: 1000000, // Max field value size in bytes
    fields: 10,         // Max number of non-file fields
    fileSize: 100,      // For multipart forms, the max file size
    files: 1,           // Max number of file fields
    headerPairs: 2000   // Max number of header key=>value pairs

If you do set upload limits, be sure to listen for limit events in the handler method. An error or exception will not occur if a limit is reached, but rather the stream will be truncated. These events are documented in more detail here.

mp.on('partsLimit', () => console.log('Maximum number of form parts reached'));

mp.on('filesLimit', () => console.log('Maximum number of files reached'));

mp.on('fieldsLimit', () => console.log('Maximim number of fields reached'));

function handler (field, file, filename, encoding, mimetype) {
  file.on('limit', () => console.log('File size limit reached'));

Additionally, you can pass per-request options to the req.multipart function'/', function (req, reply) {
  const options = { limits: { fileSize: 1000 } };
  const mp = req.multipart(handler, done, options)

  function done (err) {
    console.log('upload completed')

  function handler (field, file, filename, encoding, mimetype) {
    pump(file, fs.createWriteStream('a-destination'))

You can also use all the parsed HTTP request parameters to the body:

const options = {
  addToBody: true,
  sharedSchemaId: 'MultipartFileType', // Optional shared schema id
  onFile: (fieldName, stream, filename, encoding, mimetype, body) => {
    // Manage the file stream like you need
    // By default the data will be added in a Buffer
    // Be careful to accumulate the file in memory!
    // It is MANDATORY consume the stream, otherwise the response will not be processed!
    // The body parameter is the object that will be added to the request
  limit: { /*...*/ } // You can the limit options in any case

fastify.register(require('fastify-multipart'), options)'/', function (req, reply) {
  // This will print out:
  // {
  //   myStringField: 'example',
  //   anotherOne: 'example',
  //   myFilenameField: [{
  //     data: <Buffer>,
  //     encoding: '7bit',
  //     filename: '',
  //     limit: false,
  //     mimetype: 'text/markdown'
  //   }]
  // }


The options onFile and sharedSchemaId will be used only when addToBody: true.

The onFile option define how the file streams are managed:

  • if you don't set it the req.body.<fieldName>[index].data will be a Buffer with the data loaded in memory
  • if you set it with a function you must consume the stream, and the req.body.<fieldName>[index].data will be an empty array

Note: By default values in fields with files have array type, so if there's only one file uploaded, you can access it via req.body.<fieldName>[0].data

The sharedSchemaId parameter must provide a string ID and a shared schema will be added to your fastify instance so you will be able to apply the validation to your service like this:'/upload', {
  schema: {
    body: {
      type: 'object',
      required: ['myStringField', 'myFilenameField'],
      properties: {
        myStringField: { type: 'string' },
        myFilenameField: { type: 'array', items: 'MultipartFileType#' }
}, function (req, reply) {

The shared schema added will be like this:

  type: 'object',
  properties: {
    encoding: { type: 'string' },
    filename: { type: 'string' },
    limit: { type: 'boolean' },
    mimetype: { type: 'string' }


This project is kindly sponsored by:


Licensed under MIT.


RunKit is a free, in-browser JavaScript dev environment for prototyping Node.js code, with every npm package installed. Sign up to share your code.
Sign Up for Free