npm.io
2.0.0 • Published 6d ago

s3-file-uploader

Licence
MIT
Version
2.0.0
Deps
3
Size
17 kB
Vulns
0
Weekly
0

s3-file-uploader

A small Node.js wrapper around AWS S3 for uploading, downloading, deleting, and listing files, without writing AWS SDK boilerplate in every project that needs it.

Built on AWS SDK for JavaScript v3 (@aws-sdk/client-s3 and @aws-sdk/lib-storage). Version 1.x depended on AWS SDK v2, which reached end-of-support and printed a warning on every install. Version 2.x removes that dependency entirely. See Migrating from 1.x below if you are upgrading.

Install

npm install s3-file-uploader

Requires Node.js 20 or later, the minimum supported by the current AWS SDK v3 release line. Earlier SDK v3 releases support Node 18, but they carry an unpatched critical fast-xml-parser vulnerability (GHSA-8gc5-j5rx-235r and related advisories) that is only fixed in the Node-20-only releases, so this package does not support Node 18.

Quick start

const S3FileUploader = require('s3-file-uploader');

const uploader = new S3FileUploader({
  accessKeyId: process.env.AWS_ACCESS_KEY_ID,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  region: 'eu-west-1',
  bucketName: 'my-bucket',
});

const location = await uploader.uploadFile('./invoice.pdf', 'invoices/invoice.pdf');
console.log('Uploaded to', location);

If you omit accessKeyId / secretAccessKey (for example, running on an EC2 instance or in Lambda with an attached IAM role), the SDK falls back to its default credential provider chain automatically.

Usage examples

Upload with progress

Useful for CLIs and upload dashboards. lib-storage emits httpUploadProgress after each part completes.

await uploader.uploadFile('./video.mp4', 'videos/video.mp4', {
  onProgress: (progress) => {
    console.log(`${progress.loaded} / ${progress.total} bytes`);
  },
});
Large files (multipart upload)

No extra code needed. Once a file crosses the 5 MB part-size threshold, uploadFile automatically switches to a multipart upload and uploads parts in parallel (lib-storage defaults: 5 MB parts, 4 concurrent parts).

// A 500 MB file is uploaded in parallel 5 MB parts automatically.
await uploader.uploadFile('./backup.tar.gz', 'backups/backup.tar.gz');
Presigned URLs

Give a browser or another service temporary, credential-free access to a private object.

// A link a user can download from directly, valid for 10 minutes.
const downloadUrl = await uploader.getDownloadUrl('invoices/invoice.pdf', 600);

// A link a client can upload to directly, bypassing your server entirely.
const uploadUrl = await uploader.getUploadUrl('uploads/avatar.png', 300);
Delete and list
const keys = await uploader.listFiles('invoices/');
// ['invoices/invoice.pdf', 'invoices/invoice-2.pdf']

await uploader.deleteFile('invoices/invoice.pdf');

API

new S3FileUploader(config)
Field Type Required Description
accessKeyId string no AWS access key. Omit to use the default credential provider chain.
secretAccessKey string no AWS secret key. Required if accessKeyId is set.
region string yes AWS region the bucket lives in, e.g. 'eu-west-1'.
bucketName string yes The S3 bucket every method operates on.
s3Client S3Client no Advanced: inject your own @aws-sdk/client-s3 client instead of building one from the fields above. Mainly for tests.
uploader.uploadFile(filePath, destinationPath, options?)

Reads filePath from local disk and uploads it to destinationPath in the bucket. Returns the object's public S3 URL as a string. Automatically uses multipart upload for large files.

  • options.onProgress (optional): (progress) => void, called with { loaded, total, part, Key, Bucket } as httpUploadProgress fires.
uploader.deleteFile(destinationPath)

Deletes one object. Resolves true once S3 confirms the delete.

uploader.listFiles(prefix?)

Lists object keys in the bucket. Pass a prefix to list only a folder. Returns an array of key strings (empty array if nothing matches). Note this returns at most 1000 keys per call (S3's own ListObjectsV2 page size); it does not paginate through larger buckets.

uploader.getDownloadUrl(destinationPath, expiresInSeconds?)

Returns a presigned GET URL. Default expiry is 3600 seconds (1 hour).

uploader.getUploadUrl(destinationPath, expiresInSeconds?)

Returns a presigned PUT URL. Default expiry is 3600 seconds (1 hour). The caller uploading through this URL sends the raw file body as the PUT request body; it does not accept multipart form data.

Limits, honestly

  • No retry policy beyond what the AWS SDK does by default. A flaky network connection can still fail an upload; catch and retry in your own code if that matters to you.
  • listFiles does not paginate. A bucket prefix with more than 1000 objects only returns the first page.
  • No built-in file-type or size validation before upload. Check that yourself if you accept files from untrusted users.
  • Credentials passed in config are used as-is; this package does not store, cache, or send them anywhere except to AWS.

Migrating from 1.x

Version 2.0.0 replaces the aws-sdk (v2) dependency with the modular AWS SDK v3 (@aws-sdk/client-s3, @aws-sdk/lib-storage, @aws-sdk/s3-request-presigner). This is a breaking change for anyone who reached past the public API into SDK internals.

Unchanged, no code changes needed:

  • new S3FileUploader({ accessKeyId, secretAccessKey, region, bucketName })
  • uploader.uploadFile(filePath, destinationPath) still returns the S3 location URL string.

Changed:

  • uploader.s3 used to be an AWS.S3 instance (SDK v2). It is now an S3Client instance (SDK v3). Any code that called v2-style methods directly on uploader.s3 (e.g. uploader.s3.upload(params).promise()) needs to switch to v3 command syntax (uploader.s3.send(new PutObjectCommand(params))), or better, use the new uploadFile / deleteFile / listFiles methods instead of reaching into uploader.s3 at all.
  • The aws-sdk package is no longer a dependency. If your own code also imported aws-sdk directly (separately from this package), that import keeps working only as long as you keep aws-sdk in your own package.json; consider migrating it too before v2 support ends fully.

New in 2.0.0: deleteFile, listFiles, getDownloadUrl, getUploadUrl, upload progress via options.onProgress, and automatic multipart upload for large files.

Testing

The test suite runs entirely offline with Node's built-in test runner. No AWS account, credentials, or network access needed.

npm test

Contributing

See CONTRIBUTING.md.

Security

See SECURITY.md.

License

MIT, see LICENSE.

Author

Tisankan Jeyakumar Email: hello@tisankan.dev Website: https://tisankan.dev GitHub: https://github.com/Tisankan-dev

Keywords