Repix
Self-hosted image transformation service. Resize, crop, and convert images on-the-fly via URL. No SDK required.
Features
URL-based API
Transform images via intuitive URL patterns. No SDK required—just construct URLs with presets or inline parameters.
Modern Formats
Full support for JPEG, PNG, WebP, and AVIF. Automatic format conversion with quality optimization.
Preset System
General-purpose presets with incremental sizes (xs 64px → xl 1024px → full) for icons, thumbnails, cards, galleries, and more. Define custom presets or restrict to presets for security.
Docker Ready
Multi-stage Dockerfile. Deploy to Render, Railway, Fly.io, or Cloudflare.
Secure by Default
Configurable dimension limits, fetch timeouts, and preset-only mode to prevent abuse.
Logging
Structured request logging. Optional OTLP drain for PostHog, Datadog, or any OTLP-compatible backend.
Default Presets
General-purpose presets with incremental sizes for various use cases—icons, thumbnails, cards, galleries, hero images, and more. Use them out of the box or override with custom presets via the
PRESETS env var.| Preset | Value | Use case |
|---|---|---|
xs | w=64,q=85 | Icons, favicons |
sm | w=128,q=85 | Small thumbnails |
md | w=256,q=85 | Cards, list items |
lg | w=512,q=85 | Gallery, detail views |
xl | w=1024,q=85 | Hero images, lightbox |
full | q=85 | Unresized, quality-only |
placeholder | w=64,q=50,blur=15 | Low-quality image placeholder (LQIP) |
FAQ
Frequently asked questions about Repix.
Deploy Repix on your own domain (e.g.
img.yourdomain.com). All image URLs will show your Repix domain—users see https://img.yourdomain.com/sm/path/to/image.jpg, not your S3, R2, or CDN origin. The source URL lives in the path, but the browser address bar and referrer show only your domain. Your storage backend stays hidden.Use several controls together: set
ALLOW_CUSTOM_TRANSFORMS=false and define presets in PRESETS so only allowed transformations work. Lower IMAGE_MAX_WIDTH and IMAGE_MAX_HEIGHT (e.g. 1024) to cap output size. Reduce FETCH_TIMEOUT for slow or abusive origins. Set ALLOW_ORIGINAL_IMAGE=false to block unprocessed passthrough. Optionally restrict CORS_ORIGIN to your app's domain.Use presets instead of inline parameters. Compare
https://img.yourdomain.com/sm/example.com/photo.jpg (clean) vs https://img.yourdomain.com/w=128,q=85/example.com/photo.jpg (verbose). Define short preset names in PRESETS for your common sizes and fits—e.g. thumb, card, hero—and use those in URLs.Repix uses the PRESETS env var (JSON). Put it in .env for easier editing. For many presets, use a single-line JSON string or build it from a script:
# In .env
PRESETS='{"thumb":"w=200,h=200,fit=cover","card":"w=400,h=300,fit=cover","hero":"w=1200,h=600,fit=cover","avatar":"w=100,h=100,fit=cover,f=webp,q=85"}'
You can also keep a presets.json file and inject it: PRESETS=$(cat presets.json) before starting the server.
Yes. Repix fetches from any publicly accessible HTTPS URL. Use different domains in the path for each request:
https://img.yourdomain.com/sm/cdn1.com/photo.jpg and https://img.yourdomain.com/sm/bucket.s3.amazonaws.com/other.png both work. SOURCE_PREFIX (default https://) is prepended to the path, so you can mix S3, R2, your CDN, and other origins in the same Repix instance. To restrict which origins are allowed, set SOURCE_HOSTNAME to a comma-separated list (e.g. cdn.example.com,images.example.com); when set, only those hostnames are accepted.
