Node.js › File Uploads & Media Processing
How would you implement direct-to-S3 file uploads from a client, avoiding routing large file uploads through your Node.js server entirely?
AdvancedAnswer
Rather than having the client upload a file to your Node.js server, which then re-uploads it to S3 (doubling bandwidth usage and tying up server resources for the duration of potentially large uploads), you generate a pre-signed S3 URL server-side (a temporary, cryptographically-signed URL granting time-limited permission to upload directly to a specific S3 location) and return it to the client, which then uploads the file directly to S3 using that URL, with your server never touching the actual file bytes at all.
const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');
const { getSignedUrl } = require('@aws-sdk/s3-request-presigner');
app.post('/upload-url', async (req, res) => {
const command = new PutObjectCommand({ Bucket: 'my-bucket', Key: `uploads/${crypto.randomUUID()}` });
const url = await getSignedUrl(s3Client, command, { expiresIn: 300 });
res.json({ uploadUrl: url });
});Real-world example A video-sharing platform generates a pre-signed S3 URL for each upload request, letting users upload multi-gigabyte video files directly from their browser to S3, completely bypassing the Node.js server for the actual (potentially very slow) file transfer.