Skip to main content

Upload files to S3-compatible storage

The AWS SDK works with any S3-compatible store, including Amazon S3 and Cloudflare R2. This example uploads an object, then creates a presigned URL that grants temporary read access without exposing your credentials. Set AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and S3_BUCKET; for R2 also set S3_ENDPOINT to your account's endpoint.

import {
  GetObjectCommand,
  PutObjectCommand,
  S3Client,
} from "npm:@aws-sdk/client-s3";
import { getSignedUrl } from "npm:@aws-sdk/s3-request-presigner";
region "auto" and a custom endpoint target R2; for Amazon S3, set a real region and omit the endpoint.
const s3 = new S3Client({
  region: Deno.env.get("AWS_REGION") ?? "auto",
  endpoint: Deno.env.get("S3_ENDPOINT"),
  credentials: {
    accessKeyId: Deno.env.get("AWS_ACCESS_KEY_ID")!,
    secretAccessKey: Deno.env.get("AWS_SECRET_ACCESS_KEY")!,
  },
});

const bucket = Deno.env.get("S3_BUCKET")!;
Upload an object. Body also accepts a stream or Uint8Array for larger files.
await s3.send(
  new PutObjectCommand({
    Bucket: bucket,
    Key: "hello.txt",
    Body: "Hello from Deno!",
    ContentType: "text/plain",
  }),
);
console.log("Uploaded hello.txt");
Presign a GET URL so a browser can download the object directly for a limited time, without your credentials.
const url = await getSignedUrl(
  s3,
  new GetObjectCommand({ Bucket: bucket, Key: "hello.txt" }),
  { expiresIn: 3600 },
);
console.log("Download URL (valid 1 hour):", url);

Run this example locally using the Deno CLI:

deno run -N -E https://docs.deno.com/examples/scripts/s3_upload.ts

Did you find what you needed?

Privacy policy