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

@page-speed/img

v0.4.9

Published

Performance-optimized React Image component. Drop-in image implementation of web.dev best practices with zero configuration.

Downloads

720

Readme

⚡ @page-speed/img

Performance-optimized React Image component - Drop-in Image implementation of web.dev best practices with zero configuration. Also a great alternative to next/image for non-Next.js projects that still need the automated image optimization tools that the Next Image component provides. Utilized throughout the OpenSite Semantic UI Platform.

Page Speed React Image Component

npm version npm downloads License TypeScript

Documentation · Quick Start · Global Defaults · Examples · Contributing


Documentation

@page-speed/img is a React-first, OptixFlow-enabled image component that ships Lighthouse-friendly markup by default. It uses useOptimizedImage from @page-speed/hooks to compute pixel-perfect src, DPR-aware srcset, and sizes on the client. Tree shaking keeps the bundle lean — only the media hook is pulled in.

Installation

pnpm add @page-speed/img

Peer deps: react and react-dom (17+). For OptixFlow optimization, supply an API key.


Usage (React / Next.js)

import { Img } from "@page-speed/img";

export function HeroImage() {
  return (
    <Img
      src="https://images.example.com/hero.jpg"
      alt="Hero"
      width={1280}
      height={720}
      eager
    />
  );
}

What you get automatically:

  • Pixel-perfect primary src sized to the rendered element (Lighthouse "Properly size images" pass).
  • DPR-aware srcset (1x/2x) for AVIF, WebP, and JPEG.
  • Lazy loading via IntersectionObserver; set eager for above-the-fold images.
  • Optional OptixFlow compression and format selection with a single prop.

Setting Global Defaults

When all or most images in your app share the same OptixFlow configuration, you can set it once globally instead of repeating optixFlowConfig on every <Img />.

✅ Recommended: <ImgDefaults /> component (SSR-safe)

The ImgDefaults component is the preferred approach for React and Next.js apps. It applies the default config inside a useEffect, which means it never runs during server-side rendering — making it safe to place in any server component tree without wrapping in a "use client" boundary at the call site.

As a wrapper around your app:

// app/layout.tsx (Next.js App Router) or src/App.tsx
import { ImgDefaults } from "@page-speed/img";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <ImgDefaults
          config={{
            apiKey: process.env.NEXT_PUBLIC_OPTIX_API_KEY!,
            compressionLevel: 80,
          }}
        >
          {children}
        </ImgDefaults>
      </body>
    </html>
  );
}

Standalone (no children required):

// Place anywhere in the tree; renders null, no visual output
import { ImgDefaults } from "@page-speed/img";

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <>
      <ImgDefaults
        config={{ apiKey: process.env.NEXT_PUBLIC_OPTIX_API_KEY! }}
      />
      {children}
    </>
  );
}

Individual <Img /> components can always override the default with their own optixFlowConfig prop:

<Img
  src="https://images.example.com/hero.jpg"
  alt="Hero"
  width={1280}
  height={720}
  // Overrides the global default for this image only
  optixFlowConfig={{ renderedFileType: "jpeg", objectFit: "cover" }}
/>

Alternative: setDefaultOptixFlowConfig() function

For purely client-side apps, scripts, or imperative initialization (e.g. outside of React's render tree), the setDefaultOptixFlowConfig function is available. Call it once at app startup before any <Img /> components mount.

import { Img, setDefaultOptixFlowConfig } from "@page-speed/img";

// Call once, e.g. in main.tsx / index.tsx before rendering
setDefaultOptixFlowConfig({
  apiKey: process.env.VITE_OPTIX_API_KEY!,
  compressionLevel: 80,
});

export function HeroImage() {
  return (
    <Img
      src="https://images.example.com/hero.jpg"
      alt="Hero"
      width={1280}
      height={720}
    />
  );
}

Note: setDefaultOptixFlowConfig is not SSR-safe on its own. In server-rendered environments (Next.js, Remix, etc.) prefer the <ImgDefaults /> component, which handles the client/server boundary automatically.

To clear or reset the global default at any point:

setDefaultOptixFlowConfig(null);

Browser global (UMD / inline script)

For vanilla HTML pages or CMS integrations using the UMD build, set the global before the component renders:

<script>
  window.PageSpeedImgDefaults = {
    optixFlowConfig: {
      apiKey: "YOUR_OPTIX_KEY",
      compressionLevel: 80,
      objectFit: "cover",
    },
  };
</script>

window.OpensiteImgDefaults and window.PAGE_SPEED_IMG_DEFAULTS are also honored for backward compatibility.


<Img /> Props

| Prop | Type | Default | Description | | ----------------------- | ----------------------------- | ------------------- | ---------------------------------------------------------------------- | | src | string | — | (Required) Image URL. | | alt | string | — | Alt text (passed through to <img>). | | width | number \| string | — | Hint for sizing and CLS prevention. | | height | number \| string | — | Hint for sizing and CLS prevention. | | eager | boolean | false | Force eager loading (above-the-fold). Equivalent to loading="eager". | | loading | "lazy" \| "eager" | "lazy" | Native loading attribute. eager prop takes precedence. | | decoding | "async" \| "sync" \| "auto" | "async" | Native decoding attribute. | | fetchPriority | "high" \| "low" \| "auto" | "high" when eager | Native fetch priority. | | sizes | string | auto-computed | Override the sizes attribute generated by useOptimizedImage. | | intersectionMargin | string | "200px" | Root margin for the lazy-load IntersectionObserver. | | intersectionThreshold | number | 0.1 | Threshold for the lazy-load IntersectionObserver. | | optixFlowConfig | OptixFlowConfig | global default | Per-image OptixFlow config. Overrides any global default. | | useDebugMode | boolean | false | Log image request details to the console. |

optixFlowConfig shape:

{
  apiKey: string;
  compressionLevel?: number;           // 1–100
  renderedFileType?: "avif" | "webp" | "jpeg" | "png";
  objectFit?: "cover" | "contain" | "fill";
}

<ImgDefaults /> Props

| Prop | Type | Description | | ---------- | ----------------- | --------------------------------------------------------------------------------------- | | config | OptixFlowConfig | The OptixFlow configuration to apply as the global default. | | children | React.ReactNode | Optional. When provided, children are rendered; otherwise the component renders null. |


UMD usage

<script
  src="https://unpkg.com/react@18/umd/react.production.min.js"
  crossorigin
></script>
<script
  src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"
  crossorigin
></script>
<script
  src="https://cdn.jsdelivr.net/npm/@page-speed/[email protected]/dist/browser/page-speed-img.umd.js"
  crossorigin
></script>

<div id="app"></div>
<script>
  const root = ReactDOM.createRoot(document.getElementById("app"));
  root.render(
    React.createElement(PageSpeedImg.Img, {
      src: "https://images.example.com/card.jpg",
      alt: "Card",
      width: 800,
      height: 600,
      optixFlowConfig: { apiKey: "YOUR_OPTIX_KEY", compressionLevel: 70 },
    }),
  );
</script>

SSR considerations

  • <Img /> is marked "use client". In Next.js App Router, place it inside a Client Component or a shared layout where the "use client" boundary is already established.
  • <ImgDefaults /> is also marked "use client" and applies its config exclusively via useEffect, so it is safe to import and render from a Server Component tree — the config call never executes on the server.
  • Guards exist for window and IntersectionObserver throughout the library, so modules can be imported safely in SSR environments without crashing.

Tree shaking

@page-speed/img only imports useOptimizedImage from @page-speed/hooks, keeping bundles small. Both ESM and CJS builds are emitted; the UMD build externalizes React and ReactDOM.


Testing

pnpm test

Roadmap

  • Add Storybook examples for common layouts (hero, gallery, card).

Contributing

PRs welcome. Please run pnpm test before submitting. See CONTRIBUTING.md for details.

License

BSD 3-Clause