npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@danilo.riedel/img-fit

v0.2.2

Published

A vanilla JS companion for img-fwd that picks the optimal image width for any rendered container.

Readme

img-fit

A tiny, dependency-free JavaScript library that picks the optimal image width for any rendered container and appends it to an img-fwd URL.

Instead of hard-coding ?rs=800 in your HTML, add data-img-fit and let the browser measure the real space available after CSS has been applied.

Why?

img-fwd resizes images on the fly with the ?rs=<width> query parameter. Choosing the right width is usually a guessing game:

  • Hard-coding one width wastes bandwidth on small screens.
  • Hard-coding many breakpoints is repetitive and error-prone.

img-fit bridges that gap: it reads the rendered container size, snaps it to a cache-friendly breakpoint, and writes the correct ?rs=<width> value for you.

Installation

npm install @danilo.riedel/img-fit

Quick start

1. Add the attribute

<img data-img-fit="https://cdn.example.com/photo.jpg" alt="Photo" />

2. Initialize

import ImgFit from '@danilo.riedel/img-fit';

ImgFit.init();

That is it. The library measures the image container, picks a width, and sets:

<img src="https://cdn.example.com/photo.jpg?rs=800" alt="Photo" />

HTML usage

You can place data-img-fit directly on an <img> or on any wrapper element. When used on a wrapper, img-fit injects an <img> inside it.

<!-- Existing image element with extra CDN parameters -->
<!-- Result: https://cdn.example.com/photo.jpg?f=webp&q=80&rs=800 -->
<img
  data-img-fit="https://cdn.example.com/photo.jpg"
  data-img-fit-params="f=webp&q=80"
  alt="Photo"
/>

<!-- Wrapper element — img-fit injects an <img> inside -->
<div
  data-img-fit="https://cdn.example.com/photo.jpg"
  data-img-fit-alt="Photo"
  data-img-fit-params="f=avif"
></div>

<!-- Explicit measurement base — measure .card width instead of the img itself -->
<div class="card">
  <img
    data-img-fit="https://cdn.example.com/photo.jpg"
    data-img-fit-base=".card"
    alt="Photo"
  />
</div>

<!-- Fallback URL when data-img-fit may be empty -->
<img
  data-img-fit-fallback="https://cdn.example.com/placeholder.jpg"
  alt="Photo"
/>

Data attributes

| Attribute | Description | |---|---| | data-img-fit | Original image URL. | | data-img-fit-alt | alt text for images injected into wrapper elements. | | data-img-fit-params | Extra img-fwd parameters, e.g. f=webp&q=80. | | data-img-fit-base | CSS selector of an ancestor to measure when the element itself has no width. | | data-img-fit-fallback | Fallback URL when data-img-fit is empty. |

JavaScript API

ImgFit.init(selector?, options?)

Scan the document and start watching every matching element.

ImgFit.init();

// Custom selector and options
ImgFit.init('[data-img-fit]', { dpr: false });

ImgFit.watch(element, options?)

Watch a single element programmatically. The url option lets you supply the image URL in JavaScript rather than via a data-img-fit attribute.

const hero = document.querySelector('#hero');
ImgFit.watch(hero, {
  url: 'https://cdn.example.com/hero.jpg',
  dpr: false
});

ImgFit.unwatch(element)

Stop watching an element and disconnect its resize observer.

ImgFit.unwatch(hero);

ImgFit.getOptimalWidth(element, options?)

Return the snapped width that would be requested for an element.

const width = ImgFit.getOptimalWidth(hero);
console.log(width); // 800

ImgFit.buildUrl(element, options?)

Return the full URL that would be assigned to an element.

const url = ImgFit.buildUrl(hero);

Options

| Option | Type | Default | Description | |---|---|---|---| | selector | string | '[data-img-fit]' | Selector used by init(). | | urlAttribute | string | 'data-img-fit' | Attribute that holds the image URL. | | altAttribute | string | 'data-img-fit-alt' | Attribute that holds injected image alt text. | | paramsAttribute | string | 'data-img-fit-params' | Attribute that holds extra img-fwd params. | | baseAttribute | string | 'data-img-fit-base' | Attribute that holds a measurement-base selector. | | fallbackAttribute | string | 'data-img-fit-fallback' | Attribute that holds a fallback URL. | | dpr | boolean | true | Multiply the measured width by window.devicePixelRatio. | | observeResize | boolean | true | Update the image when the container resizes. | | resizeDebounceMs | number | 100 | Debounce delay for resize updates. | | lazy | boolean | true | Watch loading="lazy" images with IntersectionObserver and recompute before they load. | | lazyRootMargin | string | '50px' | Root margin for the lazy-load IntersectionObserver. | | lazyThreshold | number | 0 | Visibility threshold for the lazy-load IntersectionObserver. |

Width snapping

Exact container widths would fragment caches, so img-fit snaps every value up to a breakpoint:

| Range | Step | |---|---| | < 300 px | 20 px | | 300 px – 1000 px | 50 px | | > 1000 px | 250 px |

These helpers are exported if you need them elsewhere:

import { snapWidth, applyDpr } from '@danilo.riedel/img-fit';

snapWidth(260); // 260
snapWidth(265); // 280
applyDpr(400, 2); // 800

Device pixel ratio

Devices like MacBook Retina, iPhone, and AMOLED phones report a devicePixelRatio greater than 1 — they pack 2 or 3 physical pixels into every CSS pixel. By default (dpr: true) img-fit multiplies the container width by window.devicePixelRatio before snapping, so every screen gets a sharp image without any extra config.

Concrete examples:

| Container (CSS px) | DPR | Raw width | After snap | ?rs= generated | |---|---|---|---|---| | 560 px | 1× | 560 | 600 | ?rs=600 | | 560 px | 2× | 1 120 | 1 250 | ?rs=1250 | | 260 px | 2× | 520 | 550 | ?rs=550 | | 260 px | 3× | 780 | 800 | ?rs=800 |

To request CSS pixel widths only (disables DPR multiplication):

ImgFit.init({ dpr: false });

Or per-element via watch():

ImgFit.watch(element, { dpr: false });

Lazy loading

Images with loading="lazy" are tricky because the browser may not lay them out until they are close to the viewport. img-fit solves this by registering an IntersectionObserver for every lazy image. When the image is about to become visible, the URL is recomputed using the element's real rendered size, so the requested ?rs= value is correct.

<img
  data-img-fit="https://cdn.example.com/photo.jpg"
  loading="lazy"
  alt="Photo"
/>

You can disable this behavior per element or globally:

ImgFit.init({ lazy: false });

Integration with img-fwd

img-fit only adds the ?rs=<width> query string. All other transformation parameters (f, q, g, blur, etc.) are passed through untouched.

<img
  data-img-fit="https://cdn.example.com/photo.jpg"
  data-img-fit-params="f=webp&q=80"
/>

Result:

<img src="https://cdn.example.com/photo.jpg?f=webp&q=80&rs=800" />

Point your DNS or application to an img-fwd proxy and the image will be resized and optimized automatically.

Example

See the live vanilla example in examples/vanilla/:

npx serve examples/vanilla

Then open the browser DevTools Network tab and resize the window. You will see each image request a different ?rs= value based on its rendered container.

Framework support

img-fit is vanilla JavaScript so it works in any stack. Framework-specific adapters are also available:

  • @danilo.riedel/img-fit-react
  • @danilo.riedel/img-fit-next
  • @danilo.riedel/img-fit-angular
  • @danilo.riedel/img-fit-vue

Browser support

img-fit uses ResizeObserver and IntersectionObserver when available and falls back to window.resize events. It works in all modern browsers. Internet Explorer is not supported.

License

MIT