Skip to content

@venturekit/storage

Terminal window
npm install @venturekit/storage
import { createS3Config, DEFAULT_S3_CONFIG, buildS3Config } from '@venturekit/storage';
const config = createS3Config({ bucketName: 'my-uploads', versioned: true, cdn: true });
import { createStorageClientFromEnv, sanitizeFilename } from '@venturekit/storage';
const storage = createStorageClientFromEnv(); // bucket + endpoint from the storage intent's env vars
const key = `uploads/${ctx.tenant!.id}/${sanitizeFilename(file.name)}`;
await storage.put(key, buffer, { contentType: file.type });
const url = await storage.getSignedUrl(key, { expiresIn: 900 });

A presigned PUT URL cannot limit how many bytes the client sends; a presigned POST form signs a policy that S3 enforces itself, content-length-range included:

const { url, fields } = await storage.presignUploadPost(key, {
contentType: 'image/jpeg',
maxSize: 5 * 1024 * 1024, // S3 rejects anything larger — not the client's word
expiresIn: 600,
});
// browser: FormData with `fields` in order, then the file, POSTed to `url` → 204

The policy also pins the key and content type, so a leaked form cannot be repurposed. Passing maxSize to getSignedUploadUrl now throws instead of being ignored — see the API reference.

putImage() shrinks a picture once, on the way in — never upscaled, same format in and out, format sniffed from the bytes rather than trusted from the filename — and stores the original when re-encoding would not make it smaller:

const result = await storage.putImage(`avatars/${userId}`, bytes, { maxDimension: 512, jpegQuality: 82 });
// result.outcome: 'reduced' | 'kept' | 'passthrough', result.contentType, result.bytes vs result.originalBytes

optimizeImage() and sniffImageFormat() are exported for use outside the client. Re-encoding needs the optional sharp peer; projects that never store images carry no native binary.

  • Storage bucket, lifecycle, CDN, and CORS configuration types
  • StorageClient, PutOptions, PutImageOptions, PutImageResult, OptimizeImageOptions, OptimizedImage, ImageFormat — client types
  • SignedUploadPostOptions, PresignedPostUpload, PresignedUrl, BuildPresignedPostInput, PresignedPostForm — presigned upload types
  • S3Outputs, S3InfraConfig — infrastructure types
PurposeDescription
uploadsUser-uploaded files
assetsStatic assets with CDN
backupsDatabase and app backups
logsApplication logs
  • @venturekit/core — required
  • @aws-sdk/client-s3 / @aws-sdk/s3-request-presigner — storage client
  • sharp — optional peer (image re-encoding)