writing a fast S3 preview utility in node.js.

Feb 12, 2026 / Read time: 2 min read

While adapting to a new requirement on a recent work project, which was switching from a system that self-uploads images to AWS and returns HTTPS URLs to one that communicates with an existing service and responds with S3 URIs, i faced a familiar local-development dilemma.

I wanted to keep my existing logic, which was better for debugging, but it wasn’t useful for that production. My options were to default to the AWS command-line client or a GUI like Cyberduck, but switching between multiple apps would become a bottleneck to my pace.

The solution? A quick, disposable CLI tool.

Amazon S3 supports presigned URLS—temporary links that grant access to a private object for a limited time. If you already have permission to read the object, you can generate a URL that borrows that permission and expires automatically.

With Node.js and AWS SDK v3, this is straightforward. And since the goal isn’t to build a service, but a fast utility I can run locally, I only needed two dependencies:

npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner

Here’s the entire utility in a small, maintainable block:

import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

const s3Client = new S3Client({
  region: process.env.REGION
});

async function generatePreview(s3Uri) {
  try {
    // Parse bucket and key from s3:// URL
    const urlParts = s3Uri.replace("s3://", "").split("/");
    const bucket = urlParts.shift();
    const key = urlParts.join("/");

    const command = new GetObjectCommand({
      Bucket: bucket,
      Key: key,
    });

    // Generate signed URL (expires in 1 hour)
    const signedUrl = await getSignedUrl(s3Client, command, {
      expiresIn: 3600
    });

    console.log("\n Browser Preview Link:");
    console.log("--------------------------------------------");
    console.log(signedUrl);
    console.log("--------------------------------------------\n");

  } catch (err) {
    console.error("Error generating URL:", err);
  }
}

// Read input from CLI
const inputPath = process.argv[2];

if (!inputPath) {
  console.log("Usage: node preview.js s3://your-bucket/path/to/file");
} else {
  generatePreview(inputPath);
}

Run it like this:

node preview.js s3://your-bucket/path/to/image.jpg

The output is a temporary URL you can open directly in your browser.

Why This Works

Presigned URLs don’t make objects public. They simply delegate your existing s3:GetObject permission for a short time. If you can’t read the object, the URL won’t work. If you can, the link is valid until it expires & no bucket policy changes required.