Fastify Multipart Streaming File Upload

Accept streaming multipart uploads in Fastify with per-file size limits, MIME allowlists, and disk writes that never buffer whole files.

JavascriptNodeFile Upload

Code

snippet
import fastify from 'fastify';
import multipart from '@fastify/multipart';
import { createWriteStream } from 'node:fs';
import { pipeline } from 'node:stream/promises';

const app = fastify({ logger: true });
await app.register(multipart, {
  limits: { fileSize: 25 * 1024 * 1024, files: 3, fields: 10 },
});

const ALLOWED = new Set(['image/png', 'image/jpeg', 'application/pdf']);

app.post('/upload', async (req, reply) => {
  const saved = [];

  for await (const part of req.files()) {
    if (!ALLOWED.has(part.mimetype)) {
      return reply.code(415).send({ error: 'unsupported type', type: part.mimetype });
    }
    if (part.filename === undefined) continue;

    const target = createWriteStream('uploads/' + part.filename);
    await pipeline(part.file, target);
    saved.push({ name: part.filename, bytes: part.file.bytesRead });
  }
  return { saved };
});

await app.listen({ port: 3000 });