How to use S3 getObject as a promise in Node.js
Using S3 GetObject with promises and async/await in Node.js, updated for AWS SDK v3 - including how to read the streaming Body it returns.
This article first appeared in 2022 and has been updated for 2026 to cover AWS SDK v3.
In version 3 of the AWS SDK for JavaScript, every operation returns a promise, so S3 GetObject works with async/await straight out of the box and there's no promise() chaining needed. The part that catches people out now is the response, because the Body it returns is a stream rather than a buffer.
GetObject with SDK v3
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
const s3 = new S3Client({ region: "eu-west-2" });
export const handler = async (event) => {
const response = await s3.send(new GetObjectCommand({
Bucket: "my-bucket",
Key: "my-key",
}));
// Body is a readable stream, not a buffer
const body = await response.Body.transformToString();
};
The transformToString() helper reads the stream to completion and returns the contents as a string - UTF-8 by default, or pass an encoding for anything else. There's a matching transformToByteArray() for binary objects, and for large files you can pipe response.Body like any other Node.js readable stream rather than loading the whole object into memory. One thing to be aware of: in Node.js you must consume the stream (or destroy it), because an unread Body keeps its connection occupied and can exhaust the socket pool.
The old way with SDK v2
The original version of this article covered SDK v2, where getObject took a callback unless you chained promise() onto it:
const AWS = require("aws-sdk");
const s3 = new AWS.S3({
apiVersion: "2006-03-01",
region: "eu-west-2",
});
exports.handler = async function handler(event) {
let s3Object = await s3.getObject({
Bucket: "my-bucket",
Key: "my-key"
}).promise();
}
This still runs in older codebases, but AWS ended support for SDK v2 in September 2025, so it shouldn't appear in anything new - and the Node.js Lambda runtimes from nodejs18.x onwards bundle v3, not v2. The difference to watch when migrating is the one above: v2 handed you the Body as a buffer, v3 hands you a stream, and transformToString() is the bridge.
More about S3 and Node.js
AWS SDK v3 docs for GetObjectCommand: https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/command/GetObjectCommand/