HotupdaterHot Updater
Storage Plugins

Cloudflare R2 Storage

Store your Hot Updater bundles in Cloudflare R2.

Installation

npm install @hot-updater/cloudflare --save-dev

Recommended 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-dev

Configure 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 init

This 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

  • r2Storage does not implement the runtime profile.
  • Legacy r2Storage configs without credentials use Wrangler and are slower than the S3-compatible API path.
  • For a single plugin that supports both deploy-time and runtime profiles, use s3Storage from @hot-updater/aws with R2 S3 API credentials.

Protocol

r2://

This prefix is stored in the storageUri field in the database.

On this page