Cloudflare R2 Storage
Store your Hot Updater bundles in Cloudflare R2.
Installation
npm install @hot-updater/cloudflare --save-devRecommended Approach
For a single plugin that supports both deploy-time storage and runtime presigned URLs, use the S3-compatible AWS plugin. See the AWS S3 Storage documentation for more details.
Install the AWS plugin:
npm install @hot-updater/aws --save-devConfigure with R2:
import { s3Storage } from "@hot-updater/aws";
import { defineConfig } from "hot-updater";
export default defineConfig({
storage: s3Storage({
region: "auto",
endpoint: "https://your-account-id.r2.cloudflarestorage.com",
credentials: {
accessKeyId: "your-r2-access-key-id",
secretAccessKey: "your-r2-secret-access-key",
},
bucketName: "my-r2-bucket",
}),
// ... other config
});This approach provides both the node and runtime storage profiles.
Setup
The easiest way to set up your backend is using the init command:
npx hot-updater initThis interactive command will guide you through the setup process. For details on what the init command does, see the Cloudflare documentation.
For manual configuration, use the settings below.
Create R2 S3-compatible credentials from the Cloudflare R2 API token page or follow the Cloudflare R2 API token guide.
Configuration
interface R2StorageConfig {
accountId: string; // Cloudflare account ID
bucketName: string; // R2 bucket name
credentials?: {
accessKeyId: string; // R2 S3 Access Key ID
secretAccessKey: string; // R2 S3 Secret Access Key
};
cloudflareApiToken?: string; // Legacy Wrangler fallback
basePath?: string; // Optional base path within bucket
}Usage
import { r2Storage } from "@hot-updater/cloudflare";
import { defineConfig } from "hot-updater";
export default defineConfig({
storage: r2Storage({
accountId: process.env.CLOUDFLARE_ACCOUNT_ID,
bucketName: "my-r2-bucket",
credentials: {
accessKeyId: process.env.R2_ACCESS_KEY_ID,
secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
},
}),
// ... other config
});Runtime Usage
r2Storage is a CLI/deploy-time storage plugin. It implements the node
profile and uses the R2 S3-compatible API when credentials are provided.
Configs without credentials fall back to Wrangler for backward compatibility.
Cloudflare Workers should use the Worker runtime export instead:
import { r2Storage } from "@hot-updater/cloudflare/worker";
import { createHotUpdater } from "@hot-updater/server/runtime";
export const hotUpdater = createHotUpdater({
storages: [
r2Storage({
publicBaseUrl: (context) => new URL(context!.request!.url).origin,
}),
],
// ... other options
});The Worker runtime plugin implements the runtime profile. It signs bundle
download URLs and reads small metadata files directly from the R2 binding. This
lets update checks use bundle diffing without the Worker fetching its own signed
public URL.
Limitations
r2Storagedoes not implement the runtime profile.- Legacy
r2Storageconfigs withoutcredentialsuse Wrangler and are slower than the S3-compatible API path. - For a single plugin that supports both deploy-time and runtime profiles, use
s3Storagefrom@hot-updater/awswith R2 S3 API credentials.
Protocol
r2://
This prefix is stored in the storageUri field in the database.