node-uploadx Resumable Upload Middleware

raw JSON →
6.2.1 verified Thu Apr 23 auth: no javascript

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.

error ERR_REQUIRE_ESM: require() of ES Module .../node_modules/node-uploadx/dist/index.js from ... not supported.
cause Attempting to use `require()` to import `node-uploadx` in a CommonJS context when the library or a dependency is published as an ES Module, or when Node.js is configured for strict ESM.
fix
Convert your consuming file to an ES Module by using 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
cause This error typically occurs in Express if `Uploadx.middleware` is not correctly invoked, or `Uploadx` itself is imported incorrectly and not providing a callable middleware function.
fix
Ensure 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
cause The uploaded file's size exceeds the `maxUploadSize` configured in your `Uploadx` storage options. The default limit may be too small for large files.
fix
Increase the 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.
cause The client-side application is trying to upload from a different origin (domain, port, protocol) than the server, and the server's Cross-Origin Resource Sharing (CORS) policy does not permit the request.
fix
Install and configure the 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' })).
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.
fix Upgrade `node-uploadx` to version `6.1.7` or newer to mitigate the `parse-duration` ReDoS vulnerability.
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`.
fix Upgrade `node-uploadx` to version `6.2.1` or newer to ensure the fix for prototype pollution is applied.
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.
fix Review the `aws-sdk-js-v3` migration guides and ensure your S3 client configurations (e.g., credentials, region, bucket setup) are compatible with the latest SDK version bundled or required by `@uploadx/s3`.
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.
fix Ensure `cors()` middleware is placed before `Uploadx.middleware()` in your Express app. Configure `cors({ origin: 'your-client-domain', credentials: true })` appropriately for production. For development, `origin: '*'` may be used but is insecure for production.
npm install node-uploadx
yarn add node-uploadx
pnpm add node-uploadx

This quickstart sets up an Express server with node-uploadx to handle resumable file uploads to a local disk. It demonstrates basic configuration including CORS, a custom upload directory, filename generation, and a completion callback.

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}`);
});