Skip to content

Find a component

Loading the directory…

↑ ↓ to select · Enter to open · Esc to closeBrowse all →
Contributor login

Amazon S3

S3 uploads and downloads

Bijection source
git clone https://github.com/bijectionhq/s3.git
cd s3
git checkout dbf784d116622da5871f9843073bd75bfc44696a

Bijection repository access is required. Request access.

Description

S3 uploads and downloads

Explore the package README for API concepts, configuration, and examples. Check the Bijection source for adaptation-specific setup.

Available to evaluate

Review the source and its dependencies before adopting this package. Source availability does not establish npm publication or runtime qualification.

Getting started

  1. Get the source at the revision above and read its package documentation.
  2. Check the required Bijection SDK version, dependencies, and external service credentials.
  3. Follow the package setup instructions and the guide to using components.
  4. Exercise the component in your deployment according to your project’s verification rules.

Open source

Maintained source: bijectionhq/s3. Based on H4S0/convex-S3-component. License: MIT. Consult the repository for license terms, notices, and contributor attribution.

From the upstream publisher

Convex component for S3-compatible object storage: presigned upload/download URLs and file metadata.

Explore the demo ↗

Upstream overview

From the upstream package documentation.

This Convex component integrates Amazon S3 storage by generating presigned URLs that let clients upload and download files directly to/from S3 without proxying through your Convex backend. It provides cache control headers, stable public URLs for CDN integration, and handles AWS SDK v3 authentication. The component exposes actions like generateUploadUrl and getSignedUrl that your frontend can call to get time-limited S3 access URLs.

Use cases

From the upstream package documentation.

  • Direct file uploads - Let users upload images, documents, or media files straight to S3 from the browser without hitting your server
  • Secure file downloads - Generate time-limited download URLs for private content like user documents or premium assets
  • CDN integration - Use stable public URLs with CloudFront or other CDNs for cached static assets with proper cache headers
  • Large file handling - Bypass Convex's file size limits by storing large uploads directly in S3 while keeping metadata in Convex
  • Asset versioning - Implement cache-busting strategies with versioned object keys and immutable cache headers

How it works

From the upstream package documentation.

The component wraps the AWS SDK v3 S3 client and exposes Convex actions for generating presigned URLs. You configure it by adding AWS credentials and bucket settings to your Convex environment variables, then register it in convex.config.ts using app.use(s3).

The main API includes generateUploadUrl() which returns both a presigned upload URL and a stable public URL, and getSignedUrl() for creating time-limited download links. You can set cache control headers during upload generation and configure response headers like Content-Disposition for downloads.

For production use, the component supports a publicBaseUrl option to point stable URLs at your CloudFront distribution instead of direct S3 URLs. This enables proper CDN caching while keeping the presigned URLs for actual upload/download operations. Your S3 bucket needs CORS configuration to allow direct browser uploads and appropriate IAM permissions for s3:PutObject and s3:GetObject operations.

Upstream package FAQ

What AWS permissions does the Convex S3 Component need?

The component requires IAM permissions for s3:PutObject and s3:GetObject on your S3 bucket. You also need to configure CORS on your bucket to allow direct browser uploads with GET and PUT methods from your allowed origins.

How do I configure a CDN with the Convex S3 Component?

Set the S3_PUBLIC_BASE_URL environment variable to your CloudFront or CDN domain. The Convex S3 Component will use this as the base for stable public URLs instead of the default S3 domain, enabling better caching and performance.

Can I use the Convex S3 Component for private file downloads?

Yes, the Convex S3 Component generates presigned download URLs with configurable expiration times for secure access to private S3 objects. You can also set response headers like Content-Disposition to control how browsers handle the downloaded files.

What's the difference between signed URLs and public URLs in the Convex S3 Component?

The Convex S3 Component returns both signed URLs that expire after a set time and stable public URLs that don't change for a given object key. Stable URLs are better for caching strategies, while signed URLs provide time-limited secure access.

Use with agents and CLI

Give your coding agent the component’s source identity and setup guidance.

agent-prompt.md
Help me integrate Amazon S3 with Bijection.

Read: https://bijection.com/components/s3/SKILL.md

Check SDK compatibility and dependency availability.
Follow this project's execution and verification rules.

Upstream README.md

View repository ↗

Documentation from H4S0/convex-S3-component, recorded October 23, 2026. APIs and setup may differ in the Bijection adaptation.

@hasoo/convex-s3

A Convex component for integrating Amazon S3 file storage into your Convex backend. It generates presigned upload and download URLs so your clients can talk to S3 directly without proxying files through your server.


Features

  • Generate presigned upload URLs for direct-to-S3 uploads
  • Generate presigned download URLs for time-limited access
  • Set upload cache headers like Cache-Control
  • Return a stable object URL alongside the signed upload URL
  • Works natively as a Convex component
  • Built with the official AWS SDK v3

Prerequisites

  • A Convex project
  • An AWS account with an S3 bucket
  • AWS IAM credentials with s3:PutObject and s3:GetObject permissions

Setup

1. Register the component

In your convex/convex.config.ts:

import { defineApp } from "convex/server";
import s3 from "@hasoo/convex-s3/convex.config.js";

const app = defineApp();
app.use(s3);

export default app;

If you need the packaged component API type in your app:

import type { ComponentApi } from "@hasoo/convex-s3/_generated/component.js";

2. Set environment variables

Add the following environment variables to your Convex dashboard or .env.local:

VariableDescription
S3_ACCESS_KEY_IDYour AWS access key ID
S3_SECRET_ACCESS_KEYYour AWS secret access key
S3_REGIONThe AWS region your bucket is in, for example us-east-1
S3_BUCKETThe name of your S3 bucket
S3_PUBLIC_BASE_URLOptional stable base URL, such as a CloudFront domain
S3_DEFAULT_CACHE_CONTROLOptional default Cache-Control header for uploads

Usage

Generate a presigned upload URL

Use this to let a client upload a file directly to S3 while setting cache headers on the object:

import { useAction } from "convex/react";
import { api } from "../convex/_generated/api";

function UploadButton({ file }: { file: File }) {
  const getUploadUrl = useAction(api.s3.generateUploadUrl);

  async function handleUpload() {
    const key = `uploads/${crypto.randomUUID()}-${file.name}`;
    const { url, publicUrl } = await getUploadUrl({
      key,
      contentType: file.type,
      cacheControl: "public, max-age=31536000, immutable",
    });

    await fetch(url, {
      method: "PUT",
      body: file,
      headers: { "Content-Type": file.type },
    });

    console.log("Stable object URL:", publicUrl);
  }

  return <button onClick={handleUpload}>Upload</button>;
}

Generate a presigned download URL

Use this when you need secure, expiring access to a stored file:

const url = await storage.getSignedUrl("uploads/example.png", {
  expiresIn: 3600,
  responseContentDisposition: 'inline; filename="example.png"',
});

Use stable object URLs for caching

For browser or CDN caching, prefer stable object URLs and versioned object keys:

import { S3Storage } from "@hasoo/convex-s3";

const storage = new S3Storage(component, {
  bucket: process.env.S3_BUCKET,
  region: process.env.S3_REGION,
  accessKeyId: process.env.S3_ACCESS_KEY_ID,
  secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
  publicBaseUrl: "https://cdn.example.com",
  defaultCacheControl: "public, max-age=31536000, immutable",
});

const { key, publicUrl } = await storage.generateUploadUrl({
  key: `assets/${buildHash}/logo.png`,
});

publicUrl stays the same for a given object key, which makes it a much better cache key than a presigned download URL that rotates over time.


AWS IAM Policy

Your IAM user or role needs at least the following permissions on your bucket:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:PutObject", "s3:GetObject"],
      "Resource": "arn:aws:s3:::your-bucket-name/*"
    }
  ]
}

CORS Configuration

To allow browsers to upload directly to your S3 bucket, configure CORS on the bucket:

[
  {
    "AllowedHeaders": ["*"],
    "AllowedMethods": ["GET", "PUT"],
    "AllowedOrigins": ["http://localhost:3000", "https://your-production-domain.com"],
    "ExposeHeaders": []
  }
]

Project Structure

convex-S3-component/
├── convex/
│   ├── convex.config.ts
│   ├── lib.ts
│   ├── schema.ts
│   └── _generated/
├── src/
│   └── client.ts
├── client.ts
├── package.json
└── tsconfig.build.json

The published package builds both the library client entry and the Convex component entrypoints into dist/, including dist/convex/convex.config.js and dist/convex/_generated/component.js.


Dependencies

PackagePurpose
@aws-sdk/client-s3AWS S3 API client
@aws-sdk/s3-request-presignerPresigned URL generation
convexConvex backend framework

Publish Checklist

Before publishing, the usual flow is:

pnpm install
pnpm run typecheck
pnpm run build
pnpm pack

If you want to test the tarball in another project first:

pnpm run pack:local

That gives you a local package archive you can install into a separate Convex app to verify the packaged component entry points before publishing to npm.


License

MIT

Keywords