
Security News
Open VSX Begins Implementing Pre-Publish Security Checks After Repeated Supply Chain Incidents
Following multiple malicious extension incidents, Open VSX outlines new safeguards designed to catch risky uploads earlier.
@mjackson/form-data-parser
Advanced tools
A request.formData() wrapper with streaming file upload handling
A streaming multipart/form-data parser that solves memory issues with file uploads in server environments. Built as an enhanced replacement for the native request.formData() API, it enables efficient handling of large file uploads by streaming directly to disk or cloud storage services like AWS S3 or Cloudflare R2, preventing server crashes from memory exhaustion.
request.formData() with streaming file upload supportrequest.formData() for non-multipart/form-data requestsThe native request.formData() method has a few major flaws in server environments:
In normal usage, this makes it difficult to process requests with large file uploads because they can exhaust your server's RAM and crash the application.
For attackers, this creates an attack vector where malicious actors can overwhelm your server's memory by sending large payloads with many files.
form-data-parser solves this by handling file uploads as they arrive in the request body stream, allowing you to safely store files and use either a) the File directly or b) a unique identifier for that file in the returned FormData object.
Install from npm:
npm install @mjackson/form-data-parser
The parseFormData interface allows you to define an "upload handler" function for fine-grained control of handling file uploads.
import * as fsp from 'node:fs/promises';
import type { FileUpload } from '@mjackson/form-data-parser';
import { parseFormData } from '@mjackson/form-data-parser';
// Define how to handle incoming file uploads
async function uploadHandler(fileUpload: FileUpload) {
// Is this file upload from the <input type="file" name="user-avatar"> field?
if (fileUpload.fieldName === 'user-avatar') {
let filename = `/uploads/user-${user.id}-avatar.bin`;
// Store the file safely on disk
await fsp.writeFile(filename, fileUpload.bytes);
// Return the file name to use in the FormData object so we don't
// keep the file contents around in memory.
return filename;
}
// Ignore unrecognized fields
}
// Handle form submissions with file uploads
async function requestHandler(request: Request) {
// Parse the form data from the request.body stream, passing any files
// through your upload handler as they are parsed from the stream
let formData = await parseFormData(request, uploadHandler);
let avatarFilename = formData.get('user-avatar');
if (avatarFilename != null) {
console.log(`User avatar uploaded to ${avatarFilename}`);
} else {
console.log(`No user avatar file was uploaded`);
}
}
To limit the maximum size of files that are uploaded, or the maximum number of files that may be uploaded in a single request, use the maxFileSize and maxFiles options.
import { MaxFilesExceededError, MaxFileSizeExceededError } from '@mjackson/form-data-parser';
const oneKb = 1024;
const oneMb = 1024 * oneKb;
try {
let formData = await parseFormData(request, {
maxFiles: 5,
maxFileSize: 10 * oneMb,
});
} catch (error) {
if (error instanceof MaxFilesExceededError) {
console.error(`Request may not contain more than 5 files`);
} else if (error instanceof MaxFileSizeExceededError) {
console.error(`Files may not be larger than 10 MiB`);
} else {
console.error(`An unknown error occurred:`, error);
}
}
If you're looking for a more flexible storage solution for File objects that are uploaded, this library pairs really well with the file-storage library for keeping files in various storage backends.
import { LocalFileStorage } from '@mjackson/file-storage/local';
import type { FileUpload } from '@mjackson/form-data-parser';
import { parseFormData } from '@mjackson/form-data-parser';
// Set up storage for uploaded files
const fileStorage = new LocalFileStorage('/uploads/user-avatars');
// Define how to handle incoming file uploads
async function uploadHandler(fileUpload: FileUpload) {
// Is this file upload from the <input type="file" name="user-avatar"> field?
if (fileUpload.fieldName === 'user-avatar') {
let storageKey = `user-${user.id}-avatar`;
// Put the file in storage
await fileStorage.set(storageKey, fileUpload);
// Return a lazy File object that can access the stored file when needed
return fileStorage.get(storageKey);
}
// Ignore unrecognized fields
}
file-storage - A simple key/value interface for storing FileUpload objects you get from the parsermultipart-parser - The parser used internally for parsing multipart/form-data HTTP messagesSee LICENSE
FAQs
A request.formData() wrapper with streaming file upload handling
The npm package @mjackson/form-data-parser receives a total of 115,810 weekly downloads. As such, @mjackson/form-data-parser popularity was classified as popular.
We found that @mjackson/form-data-parser demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Following multiple malicious extension incidents, Open VSX outlines new safeguards designed to catch risky uploads earlier.

Research
/Security News
Threat actors compromised four oorzc Open VSX extensions with more than 22,000 downloads, pushing malicious versions that install a staged loader, evade Russian-locale systems, pull C2 from Solana memos, and steal macOS credentials and wallets.

Security News
Lodash 4.17.23 marks a security reset, with maintainers rebuilding governance and infrastructure to support long-term, sustainable maintenance.