Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Migrating from Cloudflare Images

This page covers how to move from Cloudflare Images (imagedelivery.net) to zimgx. It maps Cloudflare's URL parameters to zimgx equivalents and outlines the differences between the two.


URL mapping

Cloudflare Images:
https://imagedelivery.net/<account-id>/<image-id>/<variant-or-options>
zimgx:
https://your-domain.com/<image-path>/<transforms>

The zimgx URL scheme is compatible with Cloudflare's path structure. A request for /<account-id>/<image-id>/<transforms> works out of the box — zimgx treats everything before the last =-containing segment as the image path. Set ZIMGX_ORIGIN_PATH_PREFIX to your account ID so zimgx strips it when fetching from origin.


Parameter translation

CloudflarezimgxNotes
width=400w=400Shorter syntax
height=300h=300
quality=85q=85
format=webpf=webp
format=autof=auto (default)Auto-negotiation is on by default
fit=coverfit=coverSame values
gravity=autog=smart or g=attentionContent-aware crop via libvips
sharpen=1sharpen=1.0
blur=5blur=5.0

Feature comparison

FeatureCloudflare Imageszimgx
Image uploadRequired (via API)Not needed — reads from your origin
StorageManaged by CloudflareYour S3/R2 bucket or HTTP server
CDNBuilt-in global CDNPlace any CDN in front (Cloudflare, Fastly, and others)
Format negotiationAutomaticAutomatic (via Accept header)
CachingCDN cacheIn-memory LRU with optional R2 tier
Named variantsYes (dashboard/API)No — transforms live in the URL
PricingPer-image stored and deliveredSelf-hosted — your infrastructure costs
AnimationNative GIF/AVIF supportGIF/WebP with frame control
Self-hostedNo (managed service)Yes (single binary)

Migration steps

1. Keep your images where they are

If your images already live in R2 or S3, point zimgx at that bucket directly. You do not need to move anything.

2. Deploy zimgx

docker run -p 8080:8080 \
  -e ZIMGX_ORIGIN_TYPE=r2 \
  -e ZIMGX_R2_ENDPOINT=https://<account>.r2.cloudflarestorage.com \
  -e ZIMGX_R2_ACCESS_KEY_ID=... \
  -e ZIMGX_R2_SECRET_ACCESS_KEY=... \
  -e ZIMGX_R2_BUCKET_ORIGINALS=my-images \
  ghcr.io/officialunofficial/zimgx:latest

3. Strip the account ID prefix

Cloudflare Images URLs include your account ID as the first path segment: /<account-id>/<image-id>/<transforms>. Your origin storage stores images by <image-id> alone.

Set ZIMGX_ORIGIN_PATH_PREFIX to your Cloudflare account ID so zimgx strips it before fetching from origin:

docker run -p 8080:8080 \
  -e ZIMGX_ORIGIN_TYPE=r2 \
  -e ZIMGX_ORIGIN_PATH_PREFIX=abc123 \
  -e ZIMGX_R2_ENDPOINT=https://<account>.r2.cloudflarestorage.com \
  -e ZIMGX_R2_ACCESS_KEY_ID=... \
  -e ZIMGX_R2_SECRET_ACCESS_KEY=... \
  -e ZIMGX_R2_BUCKET_ORIGINALS=my-images \
  ghcr.io/officialunofficial/zimgx:latest

With this setting, a request for /abc123/photo-id/w=400 fetches origin key photo-id instead of abc123/photo-id.

4. Update your image URLs

Replace Cloudflare Image URLs in your app:

# Before (Cloudflare)
https://imagedelivery.net/abc123/photo-id/w=400,format=auto
 
# After (with ZIMGX_ORIGIN_PATH_PREFIX=abc123, keep the same path)
https://your-zimgx-host.com/abc123/photo-id/w=400
 
# Or without the prefix
https://your-zimgx-host.com/photo-id/w=400

Format auto-negotiation is on by default. You do not need to specify f=auto.

5. Place a CDN in front

For production, put a CDN or reverse proxy in front of zimgx:

Client → CDN (Cloudflare, Fastly, nginx) → zimgx → R2/S3

zimgx sets Cache-Control and ETag headers automatically. The CDN caches responses at the edge. zimgx's internal cache handles the origin layer.