Migrating from Cloudflare Images
This page covers how to move from Cloudflare Images (imagedelivery.net) to imgx. It maps Cloudflare's URL parameters to imgx equivalents and outlines the differences between the two.
URL mapping
Cloudflare Images (Image Resizing):
https://<zone>/image/<options>/<source-image>imgx:
https://your-domain.com/image/<options>/<image-path>imgx uses a /image/<OPTIONS>/<SOURCE-IMAGE> URL convention: a fixed image/ prefix, then a comma-separated key=value options segment, then the source image path (everything after the options segment, which may itself contain /). A request like /image/w=400,h=300/photo-id maps directly from Cloudflare's /cdn-cgi/image/w=400,h=300/photo-id — same options and source-path shape, just without the cdn-cgi/ segment. If your origin stores images under an account-ID prefix, set IMGX_ORIGIN_PATH_PREFIX to that prefix so imgx strips it when fetching from origin — that stripping happens on the resolved image path and is unrelated to the URL parsing change above.
Parameter translation
| Cloudflare | imgx | Notes |
|---|---|---|
width=400 | w=400 | Shorter syntax |
height=300 | h=300 | |
quality=85 | q=85 | |
format=webp | f=webp | |
format=auto | f=auto (default) | Auto-negotiation is on by default |
fit=cover | fit=cover | Same values |
gravity=auto | g=smart or g=attention | Content-aware crop via libvips |
sharpen=1 | sharpen=1.0 | |
blur=5 | blur=5.0 |
Feature comparison
| Feature | Cloudflare Images | imgx |
|---|---|---|
| Image upload | Required (via API) | Not needed — reads from your origin |
| Storage | Managed by Cloudflare | Your S3/R2 bucket or HTTP server |
| CDN | Built-in global CDN | Place any CDN in front (Cloudflare, Fastly, and others) |
| Format negotiation | Automatic | Automatic (via Accept header) |
| Caching | CDN cache | In-memory LRU with optional R2 tier |
| Named variants | Yes (dashboard/API) | No — transforms live in the URL |
| Pricing | Per-image stored and delivered | Self-hosted — your infrastructure costs |
| Animation | Native GIF/AVIF support | GIF/WebP with frame control |
| Self-hosted | No (managed service) | Yes (single binary) |
Migration steps
1. Keep your images where they are
If your images already live in R2 or S3, point imgx at that bucket directly. You do not need to move anything.
2. Deploy imgx
docker run -p 8080:8080 \
-e IMGX_ORIGIN_TYPE=r2 \
-e IMGX_R2_ENDPOINT=https://<account>.r2.cloudflarestorage.com \
-e IMGX_R2_ACCESS_KEY_ID=... \
-e IMGX_R2_SECRET_ACCESS_KEY=... \
-e IMGX_R2_BUCKET_ORIGINALS=my-images \
ghcr.io/officialunofficial/imgx:latest3. Strip the account ID prefix
If you're migrating from imagedelivery.net, Cloudflare Images URLs include your account ID as a path segment ahead of the image ID: /<account-id>/<image-id>/<variant-or-options>. Your origin storage stores images by <image-id> alone.
Set IMGX_ORIGIN_PATH_PREFIX to your Cloudflare account ID so imgx strips it from the resolved image path before fetching from origin:
docker run -p 8080:8080 \
-e IMGX_ORIGIN_TYPE=r2 \
-e IMGX_ORIGIN_PATH_PREFIX=abc123 \
-e IMGX_R2_ENDPOINT=https://<account>.r2.cloudflarestorage.com \
-e IMGX_R2_ACCESS_KEY_ID=... \
-e IMGX_R2_SECRET_ACCESS_KEY=... \
-e IMGX_R2_BUCKET_ORIGINALS=my-images \
ghcr.io/officialunofficial/imgx:latestWith this setting, a request for /image/w=400/abc123/photo-id resolves an image path of abc123/photo-id, and IMGX_ORIGIN_PATH_PREFIX strips it down to origin key photo-id instead of abc123/photo-id. This stripping is entirely about the origin key and is orthogonal to the image/<options>/ URL parsing described above.
4. Update your image URLs
Replace Cloudflare Image Resizing URLs in your app:
# Before (Cloudflare)
https://<zone>/image/w=400,format=auto/abc123/photo-id
# After (with IMGX_ORIGIN_PATH_PREFIX=abc123, keep the same path)
https://your-imgx-host.com/image/w=400/abc123/photo-id
# Or without the prefix
https://your-imgx-host.com/image/w=400/photo-idFormat 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 imgx:
Client → CDN (Cloudflare, Fastly, nginx) → imgx → R2/S3imgx sets Cache-Control and ETag headers automatically. The CDN caches responses at the edge. imgx's internal cache handles the origin layer.
If that CDN is Cloudflare and you would rather manage the edge as code than through dashboard rules, see Cloudflare Workers edge deployment for an optional Workers-based reverse proxy. It is one specific implementation of "place a CDN in front" above, not a replacement for it — you can just as well point any CDN at imgx with zero code, as described here.