npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

safepart

v1.1.0

Published

A secure, TypeScript-first multipart/form-data middleware for Express — a drop-in-friendly replacement for multer with safe defaults and no DoS footguns.

Readme

safepart

A secure, TypeScript-first multipart/form-data middleware for Express — built as a drop-in-friendly replacement for multer.

Why not just use multer?

multer is the de facto standard for file uploads in Express because nothing else fits Express's middleware model as cleanly. But it has shipped several real DoS vulnerabilities in 2026 alone:

  • Deeply nested multipart field names with no depth/count limits, forcing excessive memory/CPU allocation.
  • Malformed requests causing stack overflows.
  • Dropped connections during upload leaking memory via unclosed streams.

And every limit in multer (fileSize, files, fields, parts, etc.) is unset by default — you only get protection if you remember to configure it yourself.

safepart fixes this by design, not by patching:

  • Every limit is finite by default (see Default limits). There is no "unbounded" mode to forget to turn off.
  • No nested-object field parsing. Field names are always flat string -> string pairs, which eliminates the entire class of nested-object DoS bugs by construction — there's no recursive structure to attack.
  • Every code path drains its stream. Rejected, filtered-out, and errored file parts are always resumed/drained before the middleware rejects, so busboy never stalls mid-parse and the underlying socket never leaks.
  • Disk storage never trusts client input for filenames. diskStorage writes to a random filename by default; originalname is never used to build a path unless you explicitly opt in.
  • TypeScript-first. Full type definitions ship in the package, no @types package needed.

Install

npm install safepart

Quick start

import express from "express";
import safepart, { isSafePartError } from "safepart";

const upload = safepart(); // memoryStorage by default
const app = express();

app.post("/avatar", upload.single("avatar"), (req, res) => {
  // req.file.buffer, req.file.originalname, req.file.mimetype, req.file.size
  res.json({ received: req.file?.originalname });
});

app.use((err, req, res, next) => {
  if (isSafePartError(err)) {
    return res.status(400).json({ code: err.code, field: err.field });
  }
  next(err);
});

API

safepart(options?)

safepart({
  storage: memoryStorage() | diskStorage({...}), // default: memoryStorage()
  limits: { fileSize, files, fieldNameSize, fieldSize, fields, parts },
  fileFilter: (req, file, callback) => void,
});

Returns an object with:

  • .single(fieldname) — one file, exposed as req.file
  • .array(fieldname, maxCount?) — multiple files under one field, exposed as req.files (array)
  • .fields([{ name, maxCount? }, ...]) — multiple named fields, exposed as req.files (object keyed by field name)
  • .none() — reject any file part; only parses text fields into req.body
  • .any() — accept files under any field name (use sparingly; prefer explicit fields)

Non-multipart requests pass straight through to next() untouched.

Default limits

| Limit | Default | | --------------- | --------- | | fileSize | 10 MiB | | files | 10 | | fieldNameSize | 200 bytes | | fieldSize | 1 MiB | | fields | 100 | | parts | 200 |

Override any of them via limits. There is intentionally no way to set a limit to "unlimited."

Errors

Every rejection is a SafePartError with a stable code:

LIMIT_FILE_SIZE, LIMIT_FILE_COUNT, LIMIT_FIELD_KEY, LIMIT_FIELD_VALUE, LIMIT_FIELD_COUNT, LIMIT_PART_COUNT, LIMIT_UNEXPECTED_FILE, MALFORMED_REQUEST.

Use isSafePartError(err) to narrow the type in an Express error-handling middleware.

Storage engines

import { memoryStorage, diskStorage } from "safepart";

memoryStorage(); // buffers each file into req.file.buffer

diskStorage({
  destination: "/var/uploads", // string or (req, file) => string | Promise<string>
  filename: (req, file) => `${file.fieldname}-${Date.now()}`, // optional; random hex by default
});

Migrating from multer

The .single() / .array() / .fields() / .none() / .any() API surface matches multer intentionally. In most apps, swapping the import and adjusting error handling to check err.code (instead of err instanceof multer.MulterError plus string-matching err.code) is enough.

License

MIT