@xof/multer
v1.0.0
Published
Fast, streaming-first multipart/form-data middleware for Node.js.
Readme
@xof/multer
Fast, streaming-first
multipart/form-datamiddleware for Node.js.
@xof/multer is a lightweight and efficient multipart/form-data middleware for handling file uploads and form fields in Node.js applications.
It provides streaming request processing, configurable storage engines, upload limits, multiple-file handling, and structured errors.
Features
- 🚀 Streaming multipart parser
- 📦 Memory storage
- 💾 Disk storage
- 📁 Single file uploads
- 📚 Multiple file uploads
- 🗂️ Multiple field uploads
- 📝 Multipart form fields
- 🛡️ Configurable upload limits
- ⚡ Low memory overhead
- 🧹 Automatic cleanup on failed uploads
- ❌ Structured errors
- 🔌 Storage engine architecture
- 🟢 Native Node.js HTTP stream support
Requirements
- Node.js
>= 18
Installation
npm install @xof/multerBasic Usage
const multer = require('@xof/multer');
const upload = multer();
server.post('/upload', upload.single('file'), (req, res) => {
res.json({
status: true,
data: {
body: req.body,
file: req.file
}
});
}
);Storage
Memory Storage
Stores the uploaded file in memory.
const multer = require('@xof/multer');
const upload = multer({
storage: multer.memoryStorage()
});The resulting file contains a buffer property:
console.log(req.file.buffer);Memory storage is useful when the application needs to process the file directly without creating a permanent file on disk.
Disk Storage
Stores uploaded files on the filesystem.
const upload = multer({
storage: multer.diskStorage({
destination: './uploads'
})
});A disk-stored file can expose properties such as:
{
fieldname,
originalname,
filename,
destination,
path,
mimetype,
size
}The destination directory is created when required by the storage engine.
Upload Modes
Single File
Accept one file from a specific field.
upload.single('avatar')Example:
server.post(
'/avatar',
upload.single('avatar'),
(req, res) => {
res.json({
status: true,
data: req.file
});
}
);Multiple Files
Accept multiple files from the same field.
upload.array('photos', 10)Example:
server.post(
'/photos',
upload.array('photos', 10),
(req, res) => {
res.json({
status: true,
data: req.files
});
}
);Multiple Fields
Accept multiple configured file fields.
upload.fields([
{
name: 'avatar',
maxCount: 1
},
{
name: 'documents',
maxCount: 5
}
])Example:
server.post(
'/profile',
upload.fields([
{
name: 'avatar',
maxCount: 1
},
{
name: 'documents',
maxCount: 5
}
]),
(req, res) => {
res.json({
status: true,
data: req.files
});
}
);Any Files
Accept files from any multipart field.
upload.any()Example:
server.post(
'/files',
upload.any(),
(req, res) => {
res.json({
status: true,
data: req.files
});
}
);Only use this mode when arbitrary file fields are intentionally allowed.
No Files
Accept multipart form fields while rejecting file uploads.
upload.none()Example:
server.post(
'/form',
upload.none(),
(req, res) => {
res.json({
status: true,
data: req.body
});
}
);Form Fields
Text fields are available through req.body.
server.post(
'/register',
upload.single('avatar'),
(req, res) => {
res.json({
status: true,
data: {
username: req.body.username,
email: req.body.email
}
});
}
);Multiple values for the same field can be represented as arrays.
Upload Limits
Limits can be configured through the limits option.
const upload = multer({
limits: {
fileSize: 100 * 1024 * 1024,
files: 10,
fields: 50,
fieldSize: 1024 * 1024,
parts: 100
}
});Available options:
| Option | Description |
|---|---|
| fileSize | Maximum size of a single file |
| files | Maximum number of files |
| fields | Maximum number of form fields |
| fieldSize | Maximum size of a field |
| parts | Maximum number of multipart parts |
| fieldNameSize | Maximum field-name size |
| headerSize | Maximum multipart header size |
File Object
A processed file contains information about the uploaded file.
{
fieldname,
originalname,
encoding,
mimetype,
size
}Storage engines may add additional properties.
For example, memory storage can provide:
req.file.bufferDisk storage can provide:
req.file.filename
req.file.destination
req.file.pathError Handling
Upload errors contain a machine-readable code.
try {
// upload processing
} catch (error) {
console.log(error.code);
}Common error codes:
| Code | Description |
|---|---|
| LIMIT_FILE_SIZE | File exceeds the configured size |
| LIMIT_FILE_COUNT | File count limit exceeded |
| LIMIT_FIELD_COUNT | Field count limit exceeded |
| LIMIT_FIELD_VALUE | Field value exceeds the configured size |
| LIMIT_FIELD_KEY | Field name is too long |
| LIMIT_UNEXPECTED_FILE | Unexpected file field |
| INVALID_MULTIPART | Invalid multipart request |
| INVALID_BOUNDARY | Invalid multipart boundary |
| REQUEST_ABORTED | Upload was aborted |
API
multer(options)
Creates an upload middleware.
const upload = multer({
storage,
limits
});Options
| Option | Type | Description |
|---|---|---|
| storage | Storage | Storage engine |
| limits | Object | Multipart limits |
| fileFilter | Function | File validation |
multer.memoryStorage()
Creates a memory-based storage engine.
const storage = multer.memoryStorage();multer.diskStorage(options)
Creates a filesystem storage engine.
const storage = multer.diskStorage({
destination: './uploads'
});upload.single(field)
Accepts a single file.
upload.single('file')upload.array(field, maxCount)
Accepts multiple files from one field.
upload.array('files', 10)upload.fields(fields)
Accepts multiple configured fields.
upload.fields([
{
name: 'avatar',
maxCount: 1
},
{
name: 'files',
maxCount: 5
}
])upload.any()
Accepts files from any field.
upload.any()upload.none()
Accepts multipart fields without files.
upload.none()Example
const multer = require('@xof/multer');
const upload = multer({
storage: multer.diskStorage({
destination: './uploads'
}),
limits: {
fileSize: 100 * 1024 * 1024
}
});
server.post('/upload',
upload.single('file'), (req, res) => {
res.status(201).json({
status: true,
data: {
filename: req.file.filename,
originalname: req.file.originalname,
mimetype: req.file.mimetype,
size: req.file.size,
path: req.file.path
}
});
}
);Test with cURL:
curl -i \
-F "file=@./test.png" \
http://127.0.0.1:8080/uploadPerformance
@xof/multer processes multipart data as a stream instead of requiring the entire request to be loaded before parsing.
This makes it suitable for:
- Large file uploads
- Multiple-file uploads
- VPS applications
- Long-running Node.js services
- Memory-sensitive applications
For large uploads, disk storage is generally preferable to memory storage.
Changelog
License
Released under the MIT License.
