node-uploadx Resumable Upload Middleware
raw JSON →node-uploadx is a robust Node.js middleware designed for handling resumable file uploads, supporting protocols like Tus (implicitly, through its resumable features). It abstracts away the complexities of chunked uploads, error recovery, and storage management, making it suitable for applications requiring reliable file transfer. The library, currently at version 6.2.1, maintains a regular release cadence, primarily focusing on bug fixes, security enhancements, and minor feature additions as seen in recent patch versions. Key differentiators include its flexible storage options (local filesystem, S3, GCS), integrated metadata handling, built-in validation for file types and sizes, and extensibility for custom scenarios. It integrates seamlessly with popular Node.js frameworks like Express, providing a server-side backbone for client-side upload libraries such as Uppy or ngx-uploadx.
Common errors
error ERR_REQUIRE_ESM: require() of ES Module .../node_modules/node-uploadx/dist/index.js from ... not supported. ↓
import statements and ensuring your package.json has "type": "module" or the file ends with .mjs. error TypeError: Router.use() requires a middleware function but got a Object ↓
Uploadx.middleware() is called with its configuration object to return the actual middleware function. Verify the import statement import { Uploadx } from 'node-uploadx'; is correct and not trying to import a default export as a named one, or vice-versa. error PayloadTooLargeError: Request body size exceeds file upload limit ↓
maxUploadSize option in your Uploadx configuration, e.g., maxUploadSize: '5GB' to allow larger files. Ensure this limit aligns with your server's available resources and security policies. error Access to XMLHttpRequest at 'http://localhost:3003/uploads' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. ↓
cors middleware in your Express application *before* Uploadx.middleware. For development, app.use(cors({ origin: '*' })) can be used. For production, specify your client's exact origin, e.g., app.use(cors({ origin: 'http://your-client-domain.com' })). Warnings
breaking Versions prior to `6.1.7` of `node-uploadx` were affected by a Regular Expression Denial of Service (ReDoS) vulnerability stemming from the `parse-duration` dependency. This could lead to event loop delays or out-of-memory errors. ↓
breaking A prototype pollution vulnerability in the `extendObject` utility was patched in version `6.2.1`. Unsanitized input could potentially lead to arbitrary property injection on the `Object.prototype`. ↓
gotcha If using a separate `@uploadx/s3` module, updates to the underlying `aws-sdk-js-v3` (as seen in `6.1.6` and `6.1.4` changelogs) might introduce breaking changes in AWS S3 client configuration or API usage, especially if coming from older AWS SDK versions. ↓
gotcha Incorrect middleware ordering or CORS configuration can prevent file uploads from client-side applications. Preflight OPTIONS requests must be handled correctly, and 'Access-Control-Allow-Origin' headers must permit your client's domain. ↓
Install
npm install node-uploadx yarn add node-uploadx pnpm add node-uploadx Imports
- Uploadx wrong
const Uploadx = require('node-uploadx');correctimport { Uploadx } from 'node-uploadx'; - DiskStorage wrong
const { DiskStorage } = require('node-uploadx');correctimport { DiskStorage } from 'node-uploadx'; - S3Store wrong
import { S3Store } from 'node-uploadx';correctimport { S3Store } from '@uploadx/s3';
Quickstart
import express from 'express';
import cors from 'cors';
import { Uploadx, DiskStorage } from 'node-uploadx';
import path from 'path';
const app = express();
const PORT = process.env.PORT || 3003;
const UPLOAD_DIR = path.resolve(process.cwd(), 'uploads');
// Ensure the upload directory exists
import fs from 'fs';
if (!fs.existsSync(UPLOAD_DIR)) {
fs.mkdirSync(UPLOAD_DIR, { recursive: true });
}
app.use(cors({ origin: '*', credentials: true })); // Configure CORS appropriately for production
app.use(
'/uploads',
Uploadx.middleware({
storage: new DiskStorage({
directory: UPLOAD_DIR,
// Optional: Customize file naming
filename: (file) => {
const ext = path.extname(file.originalName);
const name = path.basename(file.originalName, ext);
return `${name}-${Date.now()}${ext}`;
},
// Optional: Set a maximum upload size
maxUploadSize: '10GB'
}),
// Optional: Callback after a file upload is complete
onComplete: (file) => {
console.log(`Upload complete for file: ${file.originalName} (${file.size} bytes) saved to ${file.filePath}`);
},
// Optional: Log level
logLevel: 'debug'
})
);
app.listen(PORT, () => {
console.log(`Upload server listening on port ${PORT}`);
console.log(`Uploads will be saved to: ${UPLOAD_DIR}`);
});