OpsCanary
awss3Practitioner

Unlocking Amazon S3 on Vercel: A Game Changer for Web and AI Applications

5 min read AWS BlogOct 14, 2026Reviewed for accuracy
Share
Practitioner — Hands-on experience recommended

The integration of Amazon S3 into the Vercel Marketplace is a significant advancement for developers looking to enhance their web and AI applications. This integration simplifies the process of creating and managing S3 buckets, allowing you to focus on building your application rather than wrestling with infrastructure. With S3’s durability, scalability, and performance, you can store everything from static assets to complex analytics data without breaking a sweat.

To get started, navigate to the Storage tab in the Vercel dashboard, select AWS, and create your S3 bucket. You’ll choose the bucket type and region, and the provisioning happens in seconds. The integration automatically sets up environment variables like AWS_REGION and S3_BUCKET_NAME, ensuring that you don’t have to manage static keys. At runtime, the awsCredentialsProvider from @vercel/functions/oidc securely exchanges a short-lived OIDC token for temporary AWS credentials, enhancing security by avoiding static key storage.

In production, leverage S3 Tables for optimized analytics and S3 Vectors for AI applications such as retrieval-augmented generation. The seamless integration means you can quickly implement features without extensive setup. However, be aware that while this integration simplifies many processes, you should still monitor your usage and performance, especially as your application scales. Keep an eye on your AWS costs, as they can add up quickly with increased storage and access patterns.

Key takeaways

  • →Create S3 buckets directly from the Vercel dashboard for quick setup.
  • →Utilize S3 Tables for automated table maintenance and analytics optimization.
  • →Implement S3 Vectors for advanced AI applications like semantic search.
  • →Avoid static AWS keys by using temporary credentials via OIDC tokens.
  • →Monitor AWS costs as your application scales to prevent unexpected charges.

Why it matters

This integration streamlines the process of managing storage for web and AI applications, allowing teams to focus on development rather than infrastructure management. It enhances security by eliminating static keys, which is crucial in production environments.

Code examples

JavaScript
1import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
2import { awsCredentialsProvider } from "@vercel/functions/oidc";
3
4const s3 = new S3Client({
5  region: process.env.AWS_REGION,
6  credentials: awsCredentialsProvider({
7    roleArn: process.env.AWS_ROLE_ARN,
8  }),
9});
10
11export async function POST(request) {
12  const formData = await request.formData();
13  const file = formData.get("file");
14
15  await s3.send(new PutObjectCommand({
16    Bucket: process.env.S3_BUCKET_NAME,
17    Key: file.name,
18    Body: Buffer.from(await file.arrayBuffer()),
19    ContentType: file.type,
20  }));
21
22  return Response.json({ success: true });
23}
JavaScript
1import { DuckDBInstance } from "@duckdb/node-api";
2import { awsCredentialsProvider } from "@vercel/functions/oidc";
3
4const creds = await awsCredentialsProvider({
5  roleArn: process.env.AWS_ROLE_ARN,
6})();
7
8const db = await DuckDBInstance.create();
9const conn = await db.connect();
10
11await conn.run("INSTALL aws; LOAD aws; INSTALL httpfs; LOAD httpfs; INSTALL iceberg; LOAD iceberg;");
12
13await conn.run(`
14  CREATE SECRET s3cred (
15    TYPE s3,
16    KEY_ID '${creds.accessKeyId}',
17    SECRET '${creds.secretAccessKey}',
18    SESSION_TOKEN '${creds.sessionToken}',
19    REGION '${process.env.AWS_REGION}'
20  );
21`);
22
23await conn.run(`
24  ATTACH '${process.env.AWS_RESOURCE_ARN}' AS s3tables (
25    TYPE iceberg,
26    ENDPOINT_TYPE s3_tables
27  );
28`);
29
30const rows = await (await conn.run(`
31  SELECT town_city, AVG(median_price) AS avg_price
32  FROM s3tables."${process.env.S3_TABLES_NAMESPACE}".town_monthly
33  GROUP BY town_city
34  ORDER BY avg_price DESC
35  LIMIT 10
36`)).getRowObjects();
JavaScript
1import { S3VectorsClient, QueryVectorsCommand } from "@aws-sdk/client-s3vectors";
2import { awsCredentialsProvider } from "@vercel/functions/oidc";
3
4const vectors = new S3VectorsClient({
5  region: process.env.AWS_REGION,
6  credentials: awsCredentialsProvider({
7    roleArn: process.env.AWS_ROLE_ARN,
8  }),
9});
10
11export async function POST(request) {
12  const { embedding } = await request.json();
13
14  const result = await vectors.send(new QueryVectorsCommand({
15    vectorBucketName: process.env.S3_VECTOR_BUCKET_NAME,
16    indexName: "documents",
17    queryVector: { float32: embedding },
18    topK: 5,
19    returnMetadata: true,
20  }));
21
22  return Response.json({ matches: result.vectors });
23}

When NOT to use this

The official docs don't call out specific anti-patterns here. Use your judgment based on your scale and requirements.

Want the complete reference?

Read official docs

Test what you just learned

Quiz questions written from this article

Take the quiz →
DigitalOceanSponsor

Simple, affordable cloud — VMs, Kubernetes, and managed databases in minutes. Trusted by 600,000+ developers. Spin up a Droplet in 60 seconds.

Try DigitalOcean →

Get the daily digest

One email. 5 articles. Every morning.

No spam. Unsubscribe anytime.