Serving webp and avif without a build step

1 September 2026

The usual way to ship modern image formats is to grow an image pipeline. You add sharp to the project, write a script that walks a folder, wire it into the build, and produce three copies of everything. Then you write a <picture> element with a <source> per format so old browsers get the jpeg.

That is a reasonable amount of machinery for "the photo should be smaller", and it only works for images that exist at build time. Anything a user uploads misses the pipeline entirely.

The shorter version

Convert when the file arrives, store the converted one, serve a single URL.

curl -X POST https://filemon.io/api/templates \
  -H "Authorization: Bearer $FILEMON_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Product", "width": 1200, "format": "webp"}'

Every upload through that template comes back as webp, whatever it went in as:

<img src="https://filemon.io/api/m1o900k8Zt8fLm3v" alt="" />

One URL, one format, no <picture>, no build step, and nothing in your repository that knows what an image codec is.

But what about browsers that cannot read webp?

They are gone. webp is supported by every browser released since 2020, including Safari from version 14. If your analytics disagree with that, you have a specific and unusual audience, and you should serve them jpeg by making the template produce jpeg.

avif is the interesting case. It compresses better than webp, often by another 20 to 30 per cent, and support is now broad but not universal. Two sane positions:

difference from avif is real but not dramatic.

is free money.

  • Pick webp and stop thinking about it. It is the safe default, and the
  • Pick avif and accept the tail. If your users are on recent phones, avif

What you should not do is spend a week building content negotiation to serve both. The saving is a few kilobytes per image; the cost is a moving part in your infrastructure forever.

Keep the original

The reason this is safe to decide quickly is that converting on upload does not throw anything away. The file you sent is kept exactly as it arrived, at the same id with 00 in the template segment:

m1o900k8Zt8fLm3v  the webp your visitors get
m1o90000Zt8fLm3v  the original they uploaded

So the decision is reversible. If avif turns out to be a mistake, or the format you want in two years does not exist yet, the untouched files are still there and a new template runs them through again.

That is the actual argument for doing this on upload: not that the pipeline is less work, though it is, but that you keep the raw material. A build step that overwrites its inputs is a decision you cannot take back.

Try it on your own files

Filemon resizes and converts on upload, so the URL you get back is already the finished file. The free plan needs no card.

Create an account · Read the documentation