High-level Cloudflare R2 storage API wrapper for generating pre-signed URLs and performing object operations
npx @tessl/cli install tessl/npm-cfkit--r2@1.0.0High-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.
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.
The library is built around two main classes:
import { R2Client, R2Bucket } from '@cfkit/r2';
import type {
R2ClientConfig,
PresignedUploadUrlOptions,
PresignedDownloadUrlOptions,
PresignedUrlResult,
UploadFileOptions,
UploadResult,
R2Object,
BucketInfo,
BucketDetails
} from '@cfkit/r2';class R2Client {
constructor(config: R2ClientConfig);
bucket(name: string): R2Bucket;
listBuckets(): Promise<BucketInfo[]>;
}
interface R2ClientConfig {
accountId: string;
accessKeyId: string;
secretAccessKey: string;
}presignedUploadUrl(options: PresignedUploadUrlOptions): Promise<PresignedUrlResult>;
presignedDownloadUrl(key: string, options?: PresignedDownloadUrlOptions): Promise<PresignedUrlResult>;uploadFile(key: string, file: Blob | File | ArrayBuffer | string, options: UploadFileOptions): Promise<UploadResult>;
getObject(key: string): Promise<R2Object & { body: Response }>;
deleteObject(key: string): Promise<void>;class R2Bucket {
getName(): string;
getInfo(): Promise<BucketDetails>;
exists(): Promise<boolean>;
objectExists(key: string): Promise<boolean>;
}| Pattern | Description |
|---|---|
| Client-side upload | Generate pre-signed URL → Client uploads via PUT → URL expires |
| Client-side download | Generate pre-signed URL → Client downloads via GET → URL expires |
| Server-side upload | Direct uploadFile() call with credentials |
| Server-side download | Direct getObject() call → Read body → Process |
| Existence check | objectExists() before operations to avoid errors |
| Metadata tracking | Use metadata option to store custom headers |
getObject() returns R2Object & { body: Response } - body is a fetch Response objectlistBuckets() 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 existBlob, File, ArrayBuffer, or stringRequirements: fetch API, Blob API, and crypto.subtle (for aws4fetch)
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);
}
}