Show Hugo: Jampack - Optimizes static website and create responsive images


Just wanted to share our last open-source project for static websites.

It takes the output of Hugo and do it’s magic:

  • Compress png and jpeg images to WebP
  • Creates responsive images sets for smaller devices
  • Creates progressive jpeg for images above the fold
  • Embed small images into HTML directly
  • Set image dimensions to avoid CLS
  • Compress assets (html, js, css)
    More details at

We are continuously improving the optimizations and are open for ideas.


Impressive and ambitious script!
Most of this can be templated in if you are using hugo but it it could be a shortcut for someone wanting to take any theme and get some optimisations.

This can cause images to squish as the height is maintained when the container is smaller than the image width.

The rewriting of img’s:
I think the fallback img src should probably be a jpg not a webp? There are a fair number of ipad2/3 users still out there.

Not sure if this came up because I had picture elements -

Hi Andrew,

Thanks for the reply.

This can cause images to squish as the height is maintained when the container is
smaller than the image width.

Yes, happens in certain conditions as you described, but I just opinionatedly think that dimensions are important for images and this should be fixed anyway. Would be good if I can find a solution to cover this use case.

WebP is indeed only supported on iPad 5 and up. 10 year device.
I could add a switch off for this and just improve the compression ratio.

jampack doesn’t support the picture tag yet and there are maybe different requirement for that. Next on the list. The picture tag would actually allow for multiple fallback from avif, webp and jpg/png.

I’m gonna check the w3c requirements but at least for img, the srcset of jampack is well accepted and provides nice performance improvements for the browser.

Thanks again for the reply, let me know if you test it further, love to hear what up in the field outside of our websites.

I love the sound of it, but wait to know the details to see if it produces a correct html all along. While things might display with setting dimensions on the img tag, if the validator complains, it’s not satisfying to me.
Also, I’m not used to npm and build script, could you tell where I should put:

"scripts": {
    "build": "vite build && jampack ./dist",


Yes this is for js ecosystem :slight_smile:

You can just run

npx @divriots/jampack ./public

Where public is the output of hugo.

(We need a page for use with Hugo)

Huh, I always loved the look of npm interfaces, so dynamic… But it gets me a whopping 74 issues ahahahah ! Can I have a detailed reading ?
Ah, it’s probably the <img srcset> tags I suppose.
So far it only compressed the static images meant to stay as is for when people request them, so not really useful so far for size, although I don’t know for speed. I didn’t know things like inlining small pictures, not possible with renderhooks I think.
What does that mean ?

invalid Invalid [loading]=“” on img src=“/Images/biology/cranes_africains_ancestrales/qafzeh_9_skull_from_israel_hu4cd73f9a6343999d1a9445006ecda38a_82110_465x394_resize_q100_h2_box_2.webp”

I checked srcset and sizes and indeed it’s recommended to use sizes with w srcsets. I have added sizes="100vw by default which is what the browser does when no sizes are provided.

Thanks for reporting @andrewd72 !

edit: available in version 0.6.2 now

1 Like

Just above the [74 issues] message should be the list.

Where is this coming from?

You can set widths and heights and not have it squish, for example a quick fix is setting a style with height: auto.

If it is for something like a thumbnail on a listing page, will it be loading much too large an image?

jampack only creates smaller images so it’s only an opportunity to get smaller images.

sizes only works with viewport sizes because browsers load images too eagerly.

I think lazy images (with dimensions) have an opportunity to get proper images size requested because the layout is done.

Let’s say the pre jampack img src is an image of 1000px wide being used sub-optimally for a listing thumbnail.
Jampack runs and creates 1000px and 700px and 400px versions?
Now you need a thumbnail that is 400px wide…
If the vw is 1024px which image gets taken, the 400px one or the 1000px one.
I think the sizes=“100vw” will make it pick the 1000px image?

You are correct.
But on mobile (viewport ~390px) image, 400px will be picked.

(Screen density make things more dramatic that this).
It’s not perfectly matching the quality required for the container of the image but it’s pickup the perfect image for the device.

You get nice savings.

The main idea is that you can throw images in your website and not worry too much about the size.

If you need to worry then you can fill in srcset or sizes and jampack will backoff because you already put care into the <img>.

Ah, sorry, a blunder of mine :wink:
I’ll see if we can choose what feature we want. I would prefer picking only what I can’t do easily in hugo.

@andrewd72 New version 0.7.2 adds a low specificifity :where(img) { height: auto; } that should cover the corner case for some images as you highlighted. And the sizes="100vw" has positive effects to performance on my testing so it even an improvement on top of behind more compliant :+1: Thanks again for your feedback.