veR2

Configuration

Client options

createVer2(options) (or new Ver2(options)) accepts:

OptionDefaultMeaning
storerequiredThe object store: S3ObjectStore for R2, MemoryObjectStore for tests
metamanifests in the bucketWhere version metadata lives. The default stores manifests under the namespace, so only R2 credentials are needed
namespace".ver2"Reserved key prefix for veR2's own objects
leaseMs60000How long an in-flight operation holds a key before it is presumed crashed and recovery may settle it
now() => new Date()Clock, for tests
newIdULID generatorVersion and operation IDs, for tests. Must return unique ASCII IDs of at most 26 characters
const ver2 = createVer2({ store, namespace: "_history", leaseMs: 120_000 });

Namespace rules

The namespace must be NFC-normalized and free of control characters and lone surrogates, made of non-empty segments separated by /, with no . or .. segments, and short enough to leave room for keys within R2's 1024-byte limit. Keys inside the namespace are rejected with INVALID_KEY.

R2 driver options

new S3ObjectStore(options) from @ver2/sdk/s3 accepts:

OptionDefaultMeaning
bucketrequiredBucket name
accountIdCloudflare account ID; the endpoint becomes https://<accountId>.r2.cloudflarestorage.com
endpointderivedExplicit endpoint. EU-jurisdiction buckets use https://<accountId>.eu.r2.cloudflarestorage.com
credentials{ accessKeyId, secretAccessKey } from an R2 API token
clientBring your own S3Client. Overrides endpoint, credentials, retries and timeouts; you must set requestChecksumCalculation and responseChecksumValidation to "WHEN_REQUIRED", which R2 needs
maxAttempts3Total attempts per request
requestTimeoutMs60000Per-request timeout, including uploading the body. Raise it for large objects on slow links
connectionTimeoutMs10000Connection timeout
allowNonR2EndpointfalseveR2's guards rely on R2-specific copy headers that other S3 servers silently ignore, so non-R2 endpoints are refused unless you opt in

Either accountId or endpoint is required.

CLI environment

The CLI reads these from the environment, then from .env.local and .env in the current directory:

VariableRequiredMeaning
R2_ACCOUNT_ID or R2_ENDPOINTone of themWhere the bucket is
R2_BUCKETyesBucket name
R2_ACCESS_KEY_IDyesAPI token access key ID
R2_SECRET_ACCESS_KEYyesAPI token secret
VER2_NAMESPACEnoOverrides the .ver2 namespace