or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

examples

edge-cases.mdreal-world-scenarios.md
index.md
tile.json

tessl/npm-cfkit--r2

High-level Cloudflare R2 storage API wrapper for generating pre-signed URLs and performing object operations

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@cfkit/r2@1.0.x

To install, run

npx @tessl/cli install tessl/npm-cfkit--r2@1.0.0

index.mddocs/

@cfkit/r2

High-level Cloudflare R2 storage API wrapper providing secure object storage operations through pre-signed URLs and direct file operations. Supports Cloudflare Workers, browsers, and Node.js environments.

Quick Start

import { R2Client } from '@cfkit/r2';

const r2 = new R2Client({
  accountId: 'your-account-id',
  accessKeyId: 'your-access-key-id',
  secretAccessKey: 'your-secret-access-key'
});

const bucket = r2.bucket('gallery');

// Generate pre-signed upload URL
const uploadUrl = await bucket.presignedUploadUrl({
  key: 'photo.jpg',
  contentType: 'image/jpeg',
  expiresIn: 3600
});

See Quick Start Guide for detailed setup instructions.

Core Concepts

Architecture

The library is built around two main classes:

  • R2Client: Account-level operations for bucket management and client initialization
  • R2Bucket: Bucket-scoped operations for object management and pre-signed URL generation

Key Capabilities

  • Pre-signed URLs: Secure, time-limited URLs for client-side uploads/downloads
  • Direct File Operations: Server-side upload, download, and delete operations
  • Bucket Management: List buckets, check existence, get bucket information
  • TypeScript Support: Full type definitions for all operations

Quick Reference

Core Imports

import { R2Client, R2Bucket } from '@cfkit/r2';

import type {
  R2ClientConfig,
  PresignedUploadUrlOptions,
  PresignedDownloadUrlOptions,
  PresignedUrlResult,
  UploadFileOptions,
  UploadResult,
  R2Object,
  BucketInfo,
  BucketDetails
} from '@cfkit/r2';

Client Initialization

class R2Client {
  constructor(config: R2ClientConfig);
  bucket(name: string): R2Bucket;
  listBuckets(): Promise<BucketInfo[]>;
}

interface R2ClientConfig {
  accountId: string;
  accessKeyId: string;
  secretAccessKey: string;
}

Pre-signed URLs

presignedUploadUrl(options: PresignedUploadUrlOptions): Promise<PresignedUrlResult>;
presignedDownloadUrl(key: string, options?: PresignedDownloadUrlOptions): Promise<PresignedUrlResult>;

Direct File Operations

uploadFile(key: string, file: Blob | File | ArrayBuffer | string, options: UploadFileOptions): Promise<UploadResult>;
getObject(key: string): Promise<R2Object & { body: Response }>;
deleteObject(key: string): Promise<void>;

Bucket Operations

class R2Bucket {
  getName(): string;
  getInfo(): Promise<BucketDetails>;
  exists(): Promise<boolean>;
  objectExists(key: string): Promise<boolean>;
}

Common Patterns

PatternDescription
Client-side uploadGenerate pre-signed URL → Client uploads via PUT → URL expires
Client-side downloadGenerate pre-signed URL → Client downloads via GET → URL expires
Server-side uploadDirect uploadFile() call with credentials
Server-side downloadDirect getObject() call → Read body → Process
Existence checkobjectExists() before operations to avoid errors
Metadata trackingUse metadata option to store custom headers

Default Behaviors

  • Pre-signed upload URLs: 86400 seconds (24 hours) expiration
  • Pre-signed download URLs: 3600 seconds (1 hour) expiration
  • getObject() returns R2Object & { body: Response } - body is a fetch Response object
  • listBuckets() returns empty array if no buckets exist (not an error)
  • exists() and objectExists() return false for non-existent buckets/objects (not an error)
  • getInfo() throws error if bucket doesn't exist
  • All operations are async and return Promises
  • File uploads accept: Blob, File, ArrayBuffer, or string

Environment Compatibility

  • Cloudflare Workers
  • Browser environments
  • Node.js (18+ with native fetch)
  • Deno
  • Bun

Requirements: fetch API, Blob API, and crypto.subtle (for aws4fetch)

Error Handling

All operations throw standard JavaScript Error objects. Always wrap operations in try-catch blocks:

try {
  await bucket.uploadFile('file.jpg', file, { contentType: 'image/jpeg' });
} catch (error) {
  if (error instanceof Error) {
    console.error('Upload failed:', error.message);
  }
}

Documentation

Guides

Examples

Reference

Security Best Practices

  1. Never expose credentials in client-side code
  2. Use appropriate expiration times for pre-signed URLs
  3. Validate file types and sizes before generating URLs
  4. Configure CORS on your R2 bucket for direct client uploads
  5. Use metadata headers to track uploads (user ID, timestamp, etc.)