imagex is a self-hostable image proxy and transformer built with Bun.
- Proxies upstream resources through
?url=... - Transforms images with Sharp-compatible options (
type,width,height,quality, etc.) - Uses filesystem cache directories by default:
.imagex/cache(source cache).imagex/transform(transform cache)
- Supports datasource loading from:
http(s)URLss3://paths (Bun runtime only, source loading)
- Uses Redis (via unstorage) for metadata cache
- Supports S3-backed transform object cache on Bun
Use the root endpoint with query parameters:
curl "http://localhost:3000/?url=https://github.com/venipa.png&type=webp&width=200&height=200"Required:
url(must be an absolutehttp://orhttps://URL)
Common transform params:
type(jpg|jpeg|png|webp|avif|gif, defaultwebp)widthorwheightorhsize(WIDTHxHEIGHT)quality(1-100)fit,positiondprwithoutEnlargementrotate,flip,flopblur,sharpen,grayscalestripMetadataeffort,lossless,nearLossless
If only width or only height is provided, the other dimension is calculated using source aspect ratio.
Returns JSON with:
- overall status
- Redis status
- S3 status (
ok,error, orskippedwhen S3 cache is disabled)
- Transform cache key is based on:
- source identity
- normalized transform options signature
- Changing any transform option creates a different cache key and a new transform cache item.
- With S3 transform cache enabled on Bun:
- on hit: stream cached object from S3
- on miss: generate transform, stream to client, and upload to S3
bun install
bun run devdocker run --rm -p 3000:3000 ghcr.io/venipa/imagex:latestFor full environment wiring (Redis, optional S3), use docker-compose.yml.
bun run wrangler:devWorker entry is src/worker.ts and uses KV bindings for metadata cache.
Core:
PORT(default3000)HOSTNAMES(allowed transform target hostnames, default*)ORIGIN_HOST(CORS origin host, default*)ALLOWED_RESPONSE_CATEGORIES(proxy-mode categories, defaultjson,xml,html,yml,text,image)DOMAIN_WHITELISTDOMAIN_BLACKLIST
Cache and transform:
IMAGE_CACHE_DIR(default.imagex/cache)IMAGE_TRANSFORM_DIR(default.imagex/transform)IMAGE_CACHE_TTL_SECONDS(default3600)IMAGE_TRANSFORM_TTL_SECONDS(default3600)IMAGE_TRANSFORM_DEFAULT_TYPE(defaultwebp)IMAGE_TRANSFORM_DEFAULT_QUALITY(default85)IMAGE_TRANSFORM_MAX_SCALE_MULTIPLIER(default1)
Datasource:
DATASOURCE_ENABLE_S3(defaultfalse)S3_ENDPOINTS3_ACCESS_KEY_IDS3_SECRET_ACCESS_KEYS3_BUCKETS3_REGIONS3_TRANSFORM_CACHE_PREFIX(default.imagex/transform)
Metadata cache:
REDIS_URL(defaultredis://localhost:6379)
Build info:
VERSION(defaultunknown)
bun run dev– start Bun server in watch modebun run start– start Bun serverbun run build– build Bun binarybun run wrangler:dev– run Worker locallybun run typecheck– TypeScript typecheck