A Vite plugin and React component for optimized images with LQIP support using vite-imagetools
npm install @son426/vite-imageThe Next.js 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 component immediately. No complex setups, just performant images.
- ⚡ 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.
---
Add it to vite.config.ts, and use it like this:
Option 1: Using query string (default)
``tsx
// 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 (
alt="Optimized Background"
fill
priority
placeholder="blur"
/>
);
}
`
Option 2: Auto-apply without query string
`tsx
// 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 (
alt="Optimized Background"
fill
priority
placeholder="blur"
/>
);
}
`
> Note: For auto-apply, you'll need to add type declarations. See the TypeScript Setup section below.
Install the package. vite-imagetools and @rollup/pluginutils are included as dependencies.
`bash`
pnpm add @son426/vite-imageor
npm install @son426/vite-imageor
yarn add @son426/vite-image
Just a standard Vite + React project.
- vite (>= 4.0.0)
- react (>= 18.0.0)
- react-dom (>= 18.0.0)
If you are using TypeScript, add the following to your project's type definition file (e.g., src/vite-env.d.ts):
`typescript`
///
///
This ensures TypeScript recognizes ?vite-image imports.
Add the plugin to your vite.config.ts:
`typescript
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:
`typescript`
viteImage({
breakpoints: [800, 1200, 1920],
});
Auto-apply without query string:
`typescript`
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:
`typescript`
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");
}
},
},
});
#### 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).
`typescript
import Image from "@son426/vite-image/react";
import bgImage from "@/assets/image.webp?vite-image";
function MyComponent() {
return
}
`
Without query string (autoApply enabled):
`typescript
// 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
`
Important:
- The src prop must receive the imported object directly. String URLs are not supported.autoApply
- When using , 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 URLsrcSet
- : Responsive srcSet stringblurDataURL
- : Low Quality Image Placeholder (base64 inline)width
- and height: Image dimensions
#### Usage Examples
Basic usage:
`tsx
import Image from "@son426/vite-image/react";
import heroImage from "@/assets/hero.jpg?vite-image";
`
Fill mode (container-filling images):
`tsx`
With priority (LCP images):
`tsx`
With blur placeholder:
`tsx`
Without placeholder:
`tsx`
Custom data URL placeholder:
`tsx`
Custom sizes:
`tsx`
With onLoad and onError callbacks:
`tsx`
alt="Hero"
onLoad={(e) => console.log("Image loaded", e)}
onError={(e) => console.error("Image failed to load", e)}
/>
With decoding:
`tsx`
With overrideSrc (SEO optimization):
`tsx`
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:
`tsx`
alt="Hero"
fill
priority
placeholder="blur"
className="rounded-lg"
onLoad={(e) => console.log("Loaded")}
/>
| 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 | No | - | Callback fired when image loads successfully |onError
| | (event: React.SyntheticEvent | 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.width
- The and height are automatically extracted from the src object.priority={true}
- When , the image is preloaded using react-dom's preload API and loaded with loading="eager" and fetchPriority="high".sizes
- When is not provided, it's automatically calculated from srcSet breakpoints.overrideSrc
- When is provided, the src attribute uses the override value (useful for SEO), while srcSet and sizes are disabled. Placeholders are also disabled.decoding
- The prop controls how the browser decodes the image: "async" (default, non-blocking), "sync" (blocking), or "auto" (browser decides).
The type returned from ?vite-image query or autoApply:
`typescript`
interface ResponsiveImageData {
src: string;
width: number;
height: number;
srcSet?: string;
blurDataURL?: string; // Base64 encoded blur placeholder (Next.js Image compatible)
}
Type definitions are included. The package also extends vite-imagetools types for better TypeScript support:
`typescript`
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.
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)blurDataURL
- Image metadata (largest breakpoint width)
- Blur placeholder (20px width, blurred, low quality, inline base64 as )
2. Image Component: The component handles:sizes
- Automatic calculation from srcSet breakpointsblur
- Placeholder display (, empty, or custom data URL)react-dom
- Priority loading with 's preload API when priority={true}`
- Responsive image loading with srcSet
- Proper aspect ratio maintenance
- Fill mode for container-filling images
MIT