or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-multiparty

multipart/form-data parser which supports streaming

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/multiparty@4.2.x

To install, run

npx @tessl/cli install tessl/npm-multiparty@4.2.0

index.mddocs/

multiparty

multiparty is a Node.js library for parsing HTTP requests with content-type multipart/form-data, specifically designed for handling file uploads with streaming support. It provides a comprehensive API for processing form data without loading entire files into memory, making it ideal for efficient file upload handling in web applications.

Package Information

  • Package Name: multiparty
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install multiparty

Core Imports

const multiparty = require('multiparty');

For ES modules:

import * as multiparty from 'multiparty';

Basic Usage

const multiparty = require('multiparty');
const http = require('http');

http.createServer(function(req, res) {
  if (req.url === '/upload' && req.method === 'POST') {
    // Parse a file upload with callback
    const form = new multiparty.Form();
    
    form.parse(req, function(err, fields, files) {
      if (err) {
        res.writeHead(400, { 'content-type': 'text/plain' });
        res.end('Error: ' + err.message);
        return;
      }
      
      res.writeHead(200, { 'content-type': 'application/json' });
      res.end(JSON.stringify({ fields, files }));
    });
  }
}).listen(8080);

Architecture

multiparty is built around several key concepts:

  • Form Class: Main parser that extends Node.js Writable stream for processing multipart data
  • Event-driven Architecture: Emits events for different parts of the parsing process (parts, fields, files, errors)
  • Streaming Support: Handles large file uploads without loading entire files into memory
  • Automatic Mode Detection: Switches between part/field/file events based on listeners attached
  • Configuration Options: Extensive options for controlling parsing behavior, limits, and file handling

Capabilities

Form Constructor

Creates a new multipart form parser with optional configuration.

/**
 * Creates a new multipart form parser
 * @param {Object} options - Configuration options
 */
function Form(options);

interface FormOptions {
  /** Encoding for incoming form fields (default: 'utf8') */
  encoding?: string;
  /** Maximum memory for all fields in bytes (default: 2MB) */
  maxFieldsSize?: number;
  /** Maximum number of fields to parse (default: 1000) */
  maxFields?: number;
  /** Maximum total bytes for all files (default: Infinity) */
  maxFilesSize?: number;
  /** Enable automatic field event emission (default: false) */
  autoFields?: boolean;
  /** Enable automatic file event emission (default: false) */
  autoFiles?: boolean;
  /** Directory for temporary file uploads (default: os.tmpdir()) */
  uploadDir?: string;
}

Form Parsing

Parses an incoming HTTP request containing multipart form data.

/**
 * Parse an HTTP request with multipart form data
 * @param {IncomingMessage} request - Node.js HTTP request object
 * @param {Function} [callback] - Optional callback for simplified usage
 */
form.parse(request, callback);

/**
 * Callback function signature when provided
 * @param {Error|null} err - Error if parsing failed
 * @param {Object} fields - Object with field names as keys, arrays of values as values
 * @param {Object} files - Object with field names as keys, arrays of file objects as values
 */
function parseCallback(err, fields, files);

Form Properties

Access current parsing state and progress information.

/** Current number of bytes received */
form.bytesReceived: number;

/** Expected total bytes from Content-Length header */
form.bytesExpected: number | null;

/** Current error state of the parser */
form.error: Error | null;

/** Array of currently opened file handles */
form.openedFiles: Array;

/** Total size of all parsed field data */
form.totalFieldSize: number;

/** Total count of parsed fields */
form.totalFieldCount: number;

/** Total size of all parsed file data */
form.totalFileSize: number;

Event Handling

multiparty uses an event-driven architecture for handling different stages of form parsing.

/**
 * Error event - emitted when parsing encounters an error
 * @param {Error} err - Error object with optional statusCode property
 */
form.on('error', function(err));

/**
 * Part event - emitted for each part in the multipart data
 * @param {ReadableStream} part - Stream for the part data
 */
form.on('part', function(part));

/**
 * Field event - emitted for each form field (requires autoFields)
 * @param {string} name - Field name
 * @param {string} value - Field value
 */
form.on('field', function(name, value));

/**
 * File event - emitted for each file upload (requires autoFiles)
 * @param {string} name - Field name for the file
 * @param {Object} file - File object with metadata
 */
form.on('file', function(name, file));

/**
 * Progress event - emitted during parsing for progress tracking
 * @param {number} bytesReceived - Total bytes received so far
 * @param {number|null} bytesExpected - Expected total bytes
 */
form.on('progress', function(bytesReceived, bytesExpected));

/**
 * Close event - emitted when parsing completes successfully
 */
form.on('close', function());

/**
 * Aborted event - emitted when request is aborted
 */
form.on('aborted', function());

Part Stream Properties

When handling part events, the part stream has additional properties for metadata.

interface PartStream extends ReadableStream {
  /** HTTP headers for this part */
  headers: Object;
  /** Field name for this part */
  name: string;
  /** Filename if this part is a file upload */
  filename?: string;
  /** Byte offset of this part in the request body */
  byteOffset: number;
  /** Size of this part in bytes (if known) */
  byteCount?: number;
}

File Object Structure

When using autoFiles mode or the parse callback, files are represented as objects with metadata.

interface FileObject {
  /** Field name for this file */
  fieldName: string;
  /** Original filename as reported by the client */
  originalFilename: string;
  /** Absolute path where the file was saved on disk */
  path: string;
  /** HTTP headers sent with this file */
  headers: Object;
  /** Size of the uploaded file in bytes */
  size: number;
}

Usage Examples

Event-based Processing

const form = new multiparty.Form({
  uploadDir: './uploads',
  maxFilesSize: 50 * 1024 * 1024 // 50MB limit
});

form.on('error', function(err) {
  console.error('Parsing error:', err.message);
  if (err.statusCode) {
    res.writeHead(err.statusCode);
  }
  res.end('Upload failed: ' + err.message);
});

form.on('part', function(part) {
  console.log('Received part:', part.name);
  if (part.filename) {
    console.log('File upload:', part.filename);
    // Handle file part
    part.on('data', function(chunk) {
      // Process file chunk
    });
  } else {
    console.log('Form field:', part.name);
    // Handle field part
    part.resume(); // Skip field data
  }
});

form.on('close', function() {
  console.log('Upload completed successfully');
  res.writeHead(200);
  res.end('Upload complete');
});

form.parse(req);

Automatic File Handling

const form = new multiparty.Form({
  uploadDir: './uploads',
  maxFilesSize: 100 * 1024 * 1024, // 100MB total
  maxFieldsSize: 2 * 1024 * 1024    // 2MB for fields
});

form.on('file', function(name, file) {
  console.log('File uploaded:', {
    field: name,
    filename: file.originalFilename,
    path: file.path,
    size: file.size
  });
  
  // File is automatically saved to disk at file.path
  // You can now move it to a permanent location
});

form.on('field', function(name, value) {
  console.log('Field received:', name, '=', value);
});

form.parse(req);

Progress Tracking

const form = new multiparty.Form();

form.on('progress', function(bytesReceived, bytesExpected) {
  if (bytesExpected) {
    const percent = Math.round((bytesReceived / bytesExpected) * 100);
    console.log(`Upload progress: ${percent}% (${bytesReceived} / ${bytesExpected} bytes)`);
  } else {
    console.log(`Upload progress: ${bytesReceived} bytes received`);
  }
});

form.parse(req);

Error Handling

multiparty provides detailed error handling with HTTP status codes for common scenarios:

  • 400 Bad Request: Malformed multipart data, missing boundary, encoding issues
  • 413 Payload Too Large: Field size, file size, or field count limits exceeded
  • 415 Unsupported Media Type: Invalid or missing Content-Type header
form.on('error', function(err) {
  console.error('Parse error:', err.message);
  
  // Check for specific error conditions
  if (err.statusCode === 413) {
    console.log('Upload too large');
  } else if (err.statusCode === 400) {
    console.log('Malformed request');
  }
  
  // Send appropriate HTTP response
  res.writeHead(err.statusCode || 500);
  res.end(err.message);
});

Configuration Recommendations

Production Settings

const form = new multiparty.Form({
  encoding: 'utf8',
  maxFieldsSize: 2 * 1024 * 1024,    // 2MB for form fields
  maxFields: 100,                     // Limit number of fields
  maxFilesSize: 50 * 1024 * 1024,     // 50MB total for files
  uploadDir: '/tmp/uploads'           // Dedicated upload directory
});

Development Settings

const form = new multiparty.Form({
  encoding: 'utf8',
  maxFieldsSize: 10 * 1024 * 1024,   // 10MB for testing
  maxFields: 1000,                    // Default
  maxFilesSize: 100 * 1024 * 1024,   // 100MB for testing
  uploadDir: './dev-uploads'          // Local development directory
});