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

@son426/vite-image

v0.2.2

Published

A Vite plugin and React component for optimized images with LQIP support using vite-imagetools

Readme

@son426/vite-image

The Next.js <Image /> experience, now in Vite.

  • Bring the power of Next.js's automatic image optimization to your Vite projects.
  • Dedicated to the Vite + React ecosystem.

Simply add the plugin to your config, and start using the <Image /> component immediately. No complex setups, just performant images.

✨ Why use this?

  • ⚡ Next.js-like Experience: Familiar Image API for those coming from Next.js.
  • 🖼️ Zero-Config Optimization: Automatic format conversion, resizing, and compression via vite-imagetools.
  • 🎨 Built-in LQIP: Automatic Low Quality Image Placeholders (blur effect) while loading.
  • 📱 Responsive Ready: Auto-generated srcSet and sizes for all viewports.
  • 🎯 Type-Safe: Full TypeScript support with tight integration.

🚀 Quick Look

Add it to vite.config.ts, and use it like this:

Option 1: Using query string (default)

// vite.config.ts
import { defineConfig } from "vite";
import { viteImage } from "@son426/vite-image/plugin";

export default defineConfig({
  plugins: [
    viteImage(), // Default breakpoints: [640, 1024, 1920]
  ],
});

// Component
import Image from "@son426/vite-image/react";
import myBg from "./assets/background.jpg?vite-image";

export default function Page() {
  return (
    <Image
      src={myBg}
      alt="Optimized Background"
      fill
      priority
      placeholder="blur"
    />
  );
}

Option 2: Auto-apply without query string

// vite.config.ts
import { defineConfig } from "vite";
import { viteImage } from "@son426/vite-image/plugin";

export default defineConfig({
  plugins: [
    viteImage({
      autoApply: {
        extensions: [".jpg"],
      },
    }),
  ],
});

// Component
import Image from "@son426/vite-image/react";
import myBg from "./assets/background.jpg"; // No query needed

export default function Page() {
  return (
    <Image
      src={myBg}
      alt="Optimized Background"
      fill
      priority
      placeholder="blur"
    />
  );
}

Note: For auto-apply, you'll need to add type declarations. See the TypeScript Setup section below.

Installation

Install the package. vite-imagetools and @rollup/pluginutils are included as dependencies.

pnpm add @son426/vite-image
# or
npm install @son426/vite-image
# or
yarn add @son426/vite-image

Requirements

Just a standard Vite + React project.

  • vite (>= 4.0.0)
  • react (>= 18.0.0)
  • react-dom (>= 18.0.0)

TypeScript Setup

If you are using TypeScript, add the following to your project's type definition file (e.g., src/vite-env.d.ts):

/// <reference types="vite/client" />
/// <reference types="@son426/vite-image/client" />

This ensures TypeScript recognizes ?vite-image imports.

Usage

1. Setup Vite Plugin

Add the plugin to your vite.config.ts:

import { defineConfig } from "vite";
import { viteImage } from "@son426/vite-image/plugin";

export default defineConfig({
  plugins: [
    viteImage(), // Default: breakpoints [640, 1024, 1920], no autoApply
  ],
});

Default configuration:

  • breakpoints: [640, 1024, 1920]
  • autoApply: undefined (requires ?vite-image query)

Configuration Options

Custom breakpoints:

viteImage({
  breakpoints: [800, 1200, 1920],
});

Auto-apply without query string:

viteImage({
  autoApply: {
    extensions: [".jpg", ".png", ".webp"],
    include: ["src/assets/**"],
    exclude: ["src/icons/**"],
  },
});

Note: include and exclude patterns are matched against actual image file paths (after alias resolution). For example, @/assets/image.jpg resolves to src/assets/image.jpg.

With vite-imagetools options:

viteImage({
  breakpoints: [640, 1024, 1920],
  autoApply: {
    extensions: [".jpg", ".png"],
    include: ["src/**"],
  },
  imagetools: {
    // vite-imagetools options
    defaultDirectives: (url) => {
      if (url.searchParams.has("vite-image")) {
        return new URLSearchParams("format=webp");
      }
    },
  },
});

2. Use the Component

Using ?vite-image query

The ?vite-image query parameter automatically generates all required image data. When using ?vite-image, the src prop must be an object (not a string).

import Image from "@son426/vite-image/react";
import bgImage from "@/assets/image.webp?vite-image";

function MyComponent() {
  return <Image src={bgImage} fill={false} alt="Description" />;
}

Without query string (autoApply enabled):

// vite.config.ts
viteImage({
  autoApply: {
    extensions: [".jpg", ".png"],
    include: ["src/assets/**"],
  },
});

// Add type declarations for autoApply extensions
// In your project's vite-env.d.ts or a custom .d.ts file:

interface ResponsiveImageData {
  src: string;
  width: number;
  height: number;
  srcSet?: string;
  blurDataURL?: string;
}

declare module "*.jpg" {
  const imageData: ResponsiveImageData;
  export default imageData;
}

declare module "*.png" {
  const imageData: ResponsiveImageData;
  export default imageData;
}

// Component
import bgImage from "@/assets/background.jpg"; // No query needed
<Image src={bgImage} alt="Background" />;

Important:

  • The src prop must receive the imported object directly. String URLs are not supported.
  • When using autoApply, you need to add type declarations for the extensions you're using in your project's type definition file (e.g., vite-env.d.ts).

The ?vite-image query (or autoApply) automatically generates:

  • src: Optimized image URL
  • srcSet: Responsive srcSet string
  • blurDataURL: Low Quality Image Placeholder (base64 inline)
  • width and height: Image dimensions

Usage Examples

Basic usage:

import Image from "@son426/vite-image/react";
import heroImage from "@/assets/hero.jpg?vite-image";

<Image src={heroImage} alt="Hero" />;

Fill mode (container-filling images):

<div style={{ position: "relative", width: "100%", height: "400px" }}>
  <Image src={bgImage} fill alt="Background" />
</div>

With priority (LCP images):

<Image src={heroImage} alt="Hero" priority />

With blur placeholder:

<Image src={heroImage} alt="Hero" placeholder="blur" />

Without placeholder:

<Image src={heroImage} alt="Hero" placeholder="empty" />

Custom data URL placeholder:

<Image src={heroImage} alt="Hero" placeholder="data:image/jpeg;base64,..." />

Custom sizes:

<Image src={heroImage} alt="Hero" sizes="(max-width: 768px) 100vw, 50vw" />

With onLoad and onError callbacks:

<Image
  src={heroImage}
  alt="Hero"
  onLoad={(e) => console.log("Image loaded", e)}
  onError={(e) => console.error("Image failed to load", e)}
/>

With decoding:

<Image src={heroImage} alt="Hero" decoding="sync" />

With overrideSrc (SEO optimization):

<Image
  src={heroImage}
  alt="Hero"
  overrideSrc="/original-image.jpg"
/>

Note: When overrideSrc is provided, the src attribute uses the override value for SEO purposes, while the optimized srcSet is disabled. Placeholders are also disabled when using overrideSrc.

Combined usage:

<div style={{ position: "relative", width: "100%", height: "600px" }}>
  <Image
    src={heroImage}
    alt="Hero"
    fill
    priority
    placeholder="blur"
    className="rounded-lg"
    onLoad={(e) => console.log("Loaded")}
  />
</div>

API

Image Props

| Prop | Type | Required | Default | Description | | ------------- | --------------------------------------------------------- | -------- | --------- | ----------------------------------------------------------------------- | | src | ResponsiveImageData | Yes | - | Image data object from ?vite-image query or autoApply | | fill | boolean | No | false | Fill container mode (requires parent with position: relative) | | sizes | string | No | auto | Sizes attribute (auto-calculated from srcSet if not provided) | | priority | boolean | No | false | High priority loading (preload + eager + fetchPriority high) | | placeholder | 'empty' \| 'blur' \| string | No | 'empty' | Placeholder type: 'empty' (none), 'blur' (blurDataURL), or data URL | | decoding | 'async' \| 'sync' \| 'auto' | No | 'async' | Image decoding strategy (Next.js Image compatible) | | overrideSrc | string | No | - | Override src attribute for SEO while using optimized images | | onLoad | (event: React.SyntheticEvent<HTMLImageElement>) => void | No | - | Callback fired when image loads successfully | | onError | (event: React.SyntheticEvent<HTMLImageElement>) => void | No | - | Callback fired when image fails to load | | className | string | No | - | Additional CSS classes | | style | CSSProperties | No | - | Additional inline styles | | ...props | ImgHTMLAttributes | No | - | All standard img element attributes |

Notes:

  • The src prop must be an object imported from ?vite-image query or via autoApply. String URLs are not supported.
  • The width and height are automatically extracted from the src object.
  • When priority={true}, the image is preloaded using react-dom's preload API and loaded with loading="eager" and fetchPriority="high".
  • When sizes is not provided, it's automatically calculated from srcSet breakpoints.
  • When overrideSrc is provided, the src attribute uses the override value (useful for SEO), while srcSet and sizes are disabled. Placeholders are also disabled.
  • The decoding prop controls how the browser decodes the image: "async" (default, non-blocking), "sync" (blocking), or "auto" (browser decides).

ResponsiveImageData

The type returned from ?vite-image query or autoApply:

interface ResponsiveImageData {
  src: string;
  width: number;
  height: number;
  srcSet?: string;
  blurDataURL?: string; // Base64 encoded blur placeholder (Next.js Image compatible)
}

TypeScript

Type definitions are included. The package also extends vite-imagetools types for better TypeScript support:

import Image from "@son426/vite-image/react";
import type { ImageProps } from "@son426/vite-image/react";

Note: When using autoApply with custom extensions, you need to define the ResponsiveImageData interface in your type definition file (as shown in the "Without query string" section above) since .d.ts files cannot use imports.

How It Works

  1. Image Processing: When you import an image with ?vite-image query or via autoApply, the plugin automatically generates:

    • Responsive srcSet (default: 640px, 1024px, 1920px widths, customizable via breakpoints)
    • Image metadata (largest breakpoint width)
    • Blur placeholder (20px width, blurred, low quality, inline base64 as blurDataURL)
  2. Image Component: The <Image /> component handles:

    • Automatic sizes calculation from srcSet breakpoints
    • Placeholder display (blur, empty, or custom data URL)
    • Priority loading with react-dom's preload API when priority={true}
    • Responsive image loading with srcSet
    • Proper aspect ratio maintenance
    • Fill mode for container-filling images

License

MIT