Node.js middleware for handling multipart/form-data, primarily used for file uploads
npx @tessl/cli install tessl/npm-multer@2.0.0Multer is a Node.js middleware for handling multipart/form-data, which is primarily used for uploading files. Built on top of busboy for maximum efficiency, it provides comprehensive file upload functionality for Express.js applications with flexible storage options, file filtering, and upload constraints.
npm install multerconst multer = require('multer');For ES modules:
import multer from 'multer';const express = require('express');
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
const app = express();
// Single file upload
app.post('/profile', upload.single('avatar'), (req, res) => {
// req.file contains the uploaded file
// req.body contains the text fields
console.log(req.file);
});
// Multiple file upload
app.post('/photos', upload.array('photos', 12), (req, res) => {
// req.files contains array of uploaded files
console.log(req.files);
});
// Mixed field upload
app.post('/profile-complete', upload.fields([
{ name: 'avatar', maxCount: 1 },
{ name: 'gallery', maxCount: 8 }
]), (req, res) => {
// req.files is an object with fieldname as key
console.log(req.files['avatar']);
console.log(req.files['gallery']);
});Multer is organized around several key components:
Primary multer factory function and instance methods for creating upload middleware tailored to different use cases.
function multer(options?: MulterOptions): MulterInstance;
interface MulterInstance {
single(fieldname: string): RequestHandler;
array(fieldname: string, maxCount?: number): RequestHandler;
fields(fields: FieldConfig[]): RequestHandler;
none(): RequestHandler;
any(): RequestHandler;
}File storage backends that determine where and how uploaded files are stored, with built-in disk and memory storage options.
const diskStorage = multer.diskStorage(options: DiskStorageOptions);
const memoryStorage = multer.memoryStorage();
interface DiskStorageOptions {
destination?: string | ((req: Request, file: File, cb: (error: Error | null, destination: string) => void) => void);
filename?: (req: Request, file: File, cb: (error: Error | null, filename: string) => void) => void;
}Comprehensive error handling with custom error types for different upload failure scenarios.
class MulterError extends Error {
constructor(code: string, field?: string);
code: string;
field?: string;
}
// Error codes
const LIMIT_PART_COUNT: string;
const LIMIT_FILE_SIZE: string;
const LIMIT_FILE_COUNT: string;
const LIMIT_FIELD_KEY: string;
const LIMIT_FIELD_VALUE: string;
const LIMIT_FIELD_COUNT: string;
const LIMIT_UNEXPECTED_FILE: string;
const MISSING_FIELD_NAME: string;interface MulterOptions {
dest?: string;
storage?: StorageEngine;
limits?: LimitsOptions;
preservePath?: boolean;
fileFilter?: (req: Request, file: File, cb: FileFilterCallback) => void;
}
interface LimitsOptions {
fieldNameSize?: number;
fieldSize?: number;
fields?: number;
fileSize?: number;
files?: number;
parts?: number;
headerPairs?: number;
}
interface FieldConfig {
name: string;
maxCount?: number;
}interface File {
fieldname: string;
originalname: string;
encoding: string;
mimetype: string;
size: number;
// DiskStorage specific
destination?: string;
filename?: string;
path?: string;
// MemoryStorage specific
buffer?: Buffer;
}interface MulterInstance {
single(fieldname: string): RequestHandler;
array(fieldname: string, maxCount?: number): RequestHandler;
fields(fields: FieldConfig[]): RequestHandler;
none(): RequestHandler;
any(): RequestHandler;
}
interface StorageEngine {
_handleFile(req: Request, file: File, cb: (error: Error | null, info?: any) => void): void;
_removeFile(req: Request, file: File, cb: (error: Error | null) => void): void;
}
// Express framework types
interface Request {
body: any;
file?: File;
files?: File[] | { [fieldname: string]: File[] };
[key: string]: any;
}
interface Response {
send(body?: any): Response;
json(body?: any): Response;
status(code: number): Response;
[key: string]: any;
}
type NextFunction = (err?: any) => void;type FileFilterCallback = (error: Error | null, acceptFile: boolean) => void;
type RequestHandler = (req: Request, res: Response, next: NextFunction) => void;