Skip to content
colis

Storage provider

colis with Cloudflare R2

S3-compatible, the region is always "auto", and the dashboard takes the CORS rule as JSON.

createBucket()
import { createBucket } from '@colis/core'

const store = createBucket({
  bucket: 'transfers',
  endpoint: `https://${process.env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,
  credentials: {
    accessKeyId: process.env.R2_ACCESS_KEY_ID!,
    secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!,
  },
  publicUrl: 'https://cdn.example.com', // optional: your R2 custom domain
})

Why this one

Cloudflare R2

R2 speaks the S3 API and ignores the region. It is the provider the delivery page’s README is written against: a bucket, an API token scoped to it, five environment variables, and a CORS rule for large files, pasted under the bucket’s settings.

From the command line

A starter configuration, and what is left to do.

init writes the file with ${VAR} references rather than secrets, so it is meant to be committed; the env file it points at is not.

colis.config.json
{
  "bucket": "transfers",
  "region": "auto",
  "endpoint": "https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com",
  "prefix": "transfers",
  "expiresIn": "24h",
  "envFile": ".env",
  "credentials": {
    "accessKeyId": "${R2_ACCESS_KEY_ID}",
    "secretAccessKey": "${R2_SECRET_ACCESS_KEY}"
  }
}

Then

  1. 01Put R2_ACCOUNT_ID, R2_ACCESS_KEY_ID and R2_SECRET_ACCESS_KEY in .env, and keep it out of git.
  2. 02The API token needs Object Read & Write on this bucket, and nothing else.
  3. 03Add a lifecycle rule that deletes objects under the prefix after a day or two.
  4. 04Run colis verifier. It performs the operations colis needs and reports what happened.

Worth knowing

Notes on R2.

region: "auto"

R2 ignores the region and the SDK insists on one. Setting an endpoint makes colis default to "auto", so there is nothing to write.

Large files

Large files go from the browser straight to the bucket, in parts. The bucket needs a CORS rule that allows PUT from your delivery page and exposes ETag; without it, small files still work.

Expiry cleanup

The expiry stops a parcel being handed over; only a lifecycle rule deletes the object. Give the prefix a rule that expires objects after a day or two, and colis verifier turns green.

Send it. They sign off. You know.

Your storage, a delivery page under your name, a webhook at every step. Nothing hosted by someone else.