Tools & SDKs
JavaScript (AWS SDK v3)
Use the modular AWS SDK v3 packages. They work in Node, Deno, Bun, and
the browser. The only change from real S3 is the endpoint
and forcePathStyle: true.
Install
npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner Client setup
import { S3Client } from "@aws-sdk/client-s3";
export const s3 = new S3Client({
region: "us-east-1",
endpoint: "https://s3.uploom.io",
forcePathStyle: true,
credentials: {
accessKeyId: process.env.UPLOOM_ACCESS_KEY!,
secretAccessKey: process.env.UPLOOM_SECRET!,
},
}); List buckets and objects
import { ListBucketsCommand, ListObjectsV2Command } from "@aws-sdk/client-s3";
const { Buckets } = await s3.send(new ListBucketsCommand({}));
console.log(Buckets);
const { Contents } = await s3.send(new ListObjectsV2Command({
Bucket: "bucket",
Prefix: "photos/",
}));
console.log(Contents); Upload (single-part)
import { PutObjectCommand } from "@aws-sdk/client-s3";
await s3.send(new PutObjectCommand({
Bucket: "bucket",
Key: "photos/2026/photo.jpg",
Body: file,
ContentType: "image/jpeg",
})); Download
import { GetObjectCommand } from "@aws-sdk/client-s3";
const { Body } = await s3.send(new GetObjectCommand({
Bucket: "bucket",
Key: "photos/2026/photo.jpg",
}));
// Node
const bytes = await Body.transformToByteArray();
// Browser
const blob = await Body.blob(); Multipart
import { Upload } from "@aws-sdk/lib-storage";
await new Upload({
client: s3,
params: { Bucket: "bucket", Key: "backups/huge.bin", Body: file },
}).done(); Presigned URL
import { PutObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const url = await getSignedUrl(
s3,
new PutObjectCommand({
Bucket: "bucket",
Key: `uploads/${crypto.randomUUID()}.bin`,
}),
{ expiresIn: 600 },
);
// In the browser:
await fetch(url, { method: "PUT", body: file }); Bundle size
The SDK is tree-shakable. Importing just @aws-sdk/client-s3
with the commands you need keeps the bundle around 60 kB gzipped.
@aws-sdk/s3-request-presigner is an extra ~5 kB.
Edge runtimes
The SDK works on all modern JS runtimes. For Cloudflare Workers, Deno,
or Bun, the default FetchHttpHandler is fine. The
Body of GetObjectCommand is always a Web
ReadableStream.