Skip to content
LogoLogo

Cloudflare Workers edge deployment

crates/imgx-edge is an optional, separate Cloudflare Worker that sits in front of an imgx origin as a thin edge-caching reverse proxy. It is not required to run imgx — it is one extra layer you can add if you specifically want Cloudflare's edge network in front of an imgx deployment and prefer to manage that layer as code.

This page explains what it is, what it deliberately is not, and how it relates to two other things that sound similar but are different.


What it is

A minimal workers-rs Worker (crates/imgx-edge) with a single fetch handler that:

  1. Lets Workers Caching check for a cached response before the handler even runs (configured declaratively via the [cache] block in crates/imgx-edge/wrangler.toml).
  2. On a cache miss, forwards the incoming request — method, headers, and body, unmodified — to a configurable upstream origin URL (IMGX_ORIGIN_URL, set in wrangler.toml's [vars] block).
  3. Returns the origin's response as-is, including its Cache-Control and ETag headers, so Workers Caching stores it correctly on the way out.

That is the entire request lifecycle. There is no transform-parameter parsing, no image logic, and no libvips anywhere in this Worker — see the next section for why.

What it deliberately is not

Not a reimplementation of imgx's transform pipeline. imgx's actual image work (crates/imgx, crates/imgx-vips) links libvips via C FFI and depends on dynamic library loading, a filesystem, and native syscalls. Cloudflare Workers run in a V8/WASM sandbox with none of those — libvips cannot run there. imgx-edge never attempts to parse w=/h=/f= transform parameters or touch pixels; it is pure routing and caching in front of a real imgx instance running somewhere that can run libvips (a VM, container, or bare metal — see Deployment).

Not required. Migrating from Cloudflare § Place a CDN in front already covers the zero-code option: point any CDN (Cloudflare's dashboard-configured caching, Fastly, nginx, etc.) at imgx and you get edge caching with no Worker to write or deploy. imgx-edge exists for the case where you specifically want that layer expressed as a Worker instead — for example, to keep it in version control alongside the rest of this repo, or because you're already running other logic in Workers and want a consistent deployment story.

Not the same Worker as the docs site. This repository's documentation site is deployed separately, as its own Workers static-assets site (apps/docs/wrangler.toml, [assets] directory = "./dist/public"), via Cloudflare's git integration connected directly to this repo rather than a CI-driven deploy. .github/workflows/docs.yml only builds the docs site as a CI check now. That deployment used to run through Cloudflare Pages (wrangler pages deploy ... --project-name=zimgx); it has since moved to a Workers static-assets deployment, which is Cloudflare's current recommended way to serve static sites. Either way, it is a completely separate deployable (a static docs site, not an image proxy) from imgx-edge, with its own wrangler.toml and its own name. imgx-edge's wrangler.toml has no routes/zone binding configured — which hostname it should front is left as an open decision, not assumed to be whatever hostname serves the docs site.

Why Workers Caching, not the Cache API

Cloudflare Workers expose two different caching mechanisms. imgx-edge uses Workers Caching (the [cache] block in wrangler.toml), not the programmatic caches.default Cache API, on purpose:

  • imgx already owns a multi-tier server-side cache (in-memory LRU with an optional R2 tier — see Architecture). Caching at the edge is meant to reduce round-trips to that origin, not to duplicate or fight with it.
  • The Cache API's cache is per-datacenter-local and not shared across Cloudflare's network. For a proxy meant to sit in front of one logical origin, that non-shared semantics is a correctness trap: the same image could be independently fetched from origin dozens of times across datacenters, and cache invalidation would need to account for that fragmentation.
  • Workers Caching is configured declaratively and applies before the fetch handler even runs on a hit, which keeps imgx-edge's code a pure pass-through rather than something that has to reason about cache keys itself.

Getting it running

cd crates/imgx-edge
cargo install worker-build   # if not already installed
# Edit wrangler.toml: set IMGX_ORIGIN_URL to your imgx deployment,
# bump compatibility_date to today, and add a routes/zone binding.
wrangler deploy

crates/imgx-edge is also a member of the root Cargo workspace so cargo fmt/cargo clippy cover it like any other crate — but it is never built with plain cargo build. It only produces a working Worker via worker-build/wrangler deploy, which cross-compile it to wasm32-unknown-unknown and wrap it in the JS shim Workers expects.