A lightweight, high-performance React image component inspired by Next.js Image, with automatic optimization, blur placeholders, and lazy loading. Zero dependencies except React.
- Automatic Image Optimization - Generates responsive images with srcSet
- Blur Placeholders - Smooth loading transitions with automatic blur generation
- Lazy Loading - Built-in lazy loading for better performance
- Responsive - Perfect for any screen size with automatic srcSet generation
- Fill Mode - Container-based sizing like CSS object-fit
- TypeScript - Full type safety included out of the box
- Configurable - Optional development warnings and custom loaders
- Tiny Bundle - Only 6.4kb (2.8kb gzipped), no external dependencies
- Performance - Optimized for Core Web Vitals and page speed
- Privacy Safe - No environment detection or data collection
bun add react-blurish-imagenpm install react-blurish-imageyarn add react-blurish-imagepnpm add react-blurish-imageimport { Image } from "react-blurish-image";
function App() {
return (
<Image
src="https://example.com/image.jpg"
alt="A beautiful landscape"
width={800}
height={600}
placeholder="blur"
quality={90}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
src |
string |
required | Image source URL |
alt |
string |
required | Alternative text for accessibility |
width |
number |
undefined |
Image width in pixels |
height |
number |
undefined |
Image height in pixels |
fill |
boolean |
false |
Fill the parent container (like object-fit) |
placeholder |
'blur' | 'empty' |
'empty' |
Placeholder type while loading |
blurDataURL |
string |
undefined |
Custom blur placeholder (auto-generated if not provided) |
quality |
number |
75 |
Image quality (1-100) |
priority |
boolean |
false |
Load image with high priority (disables lazy loading) |
loading |
'eager' | 'lazy' |
'lazy' |
Loading behavior |
unoptimized |
boolean |
false |
Skip automatic optimization |
loader |
ImageLoader |
defaultLoader |
Custom image loader function |
sizes |
string |
undefined |
Responsive image sizes attribute |
onLoad |
function |
undefined |
Callback when image loads |
onError |
function |
undefined |
Callback when image fails to load |
onLoadingComplete |
function |
undefined |
Callback when loading completes |
All standard HTML <img> attributes are supported: className, style, crossOrigin, referrerPolicy, decoding, fetchPriority, etc.
import { Image } from "react-blurish-image";
<Image
src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4"
alt="Mountain landscape"
width={800}
height={600}
placeholder="blur"
quality={90}
className="rounded-lg shadow-md"
/>;Perfect for hero sections and responsive layouts:
<div style={{ position: "relative", width: "100%", height: "50vh" }}>
<Image
src="/hero-image.jpg"
alt="Hero background"
fill
placeholder="blur"
priority
style={{ objectFit: "cover" }}
/>
</div><Image
src="/responsive-image.jpg"
alt="Responsive image"
width={1200}
height={800}
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
placeholder="blur"
quality={85}
/>For images that should load immediately:
<Image
src="/hero.jpg"
alt="Hero image"
width={1200}
height={600}
priority
placeholder="blur"
quality={95}
/>Provide your own optimized blur placeholder:
<Image
src="/image.jpg"
alt="Custom blur example"
width={600}
height={400}
placeholder="blur"
blurDataURL="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ..."
/>Enable helpful warnings during development to catch common issues like missing alt text, incorrect dimensions, or performance problems:
import { configureImage } from "react-blurish-image";
// Enable warnings during development
if (process.env.NODE_ENV === "development") {
configureImage({ enableWarnings: true });
}Development warnings help you:
- Identify images without proper alt text for accessibility
- Detect missing width/height attributes that cause layout shift
- Warn about potential performance issues
- Alert you to incorrectly configured props
- Catch common mistakes before they reach production
Integrate with your preferred CDN or image service:
import { Image, ImageLoader } from "react-blurish-image";
// Cloudinary example
const cloudinaryLoader: ImageLoader = ({ src, width, quality }) => {
const params = ["f_auto", "c_limit", `w_${width}`, `q_${quality || "auto"}`];
return `https://res.cloudinary.com/your-cloud/image/fetch/${params.join(
","
)}/${src}`;
};
// Vercel Image Optimization example
const vercelLoader: ImageLoader = ({ src, width, quality }) => {
return `/_vercel/image?url=${encodeURIComponent(src)}&w=${width}&q=${
quality || 75
}`;
};
<Image
src="https://example.com/image.jpg"
alt="CDN optimized image"
width={800}
height={600}
loader={cloudinaryLoader}
/>;<Image
src="/image.jpg"
alt="Styled image"
width={400}
height={300}
placeholder="blur"
className="rounded-xl shadow-2xl hover:scale-105 transition-transform"
/><Image
src="/image.jpg"
alt="Styled image"
width={400}
height={300}
placeholder="blur"
style={{
borderRadius: "12px",
boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
transition: "transform 0.2s ease-in-out",
}}
/>- Always provide dimensions: Use
widthandheightto prevent layout shift - Use blur placeholders: Add
placeholder="blur"for better perceived performance - Optimize quality: Use
quality={85}for the best balance of size and quality - Enable priority loading: Use
priorityfor above-the-fold images - Leverage responsive images: Use the
sizesprop for responsive layouts - Custom loaders: Integrate with CDNs for optimal delivery and caching
<Image
src="/might-fail.jpg"
alt="Image with error handling"
width={400}
height={300}
onError={(e) => {
console.log("Image failed to load:", e);
// Could set fallback image here
}}
onLoadingComplete={(img) => {
console.log(
"Image loaded successfully:",
img.naturalWidth,
"x",
img.naturalHeight
);
}}
/>function ImageGallery({ images }) {
return (
<div className="grid grid-cols-3 gap-4">
{images.map((image, index) => (
<Image
key={image.id}
src={image.url}
alt={image.description}
width={300}
height={200}
placeholder="blur"
priority={index < 3} // Priority for first 3 images
sizes="(max-width: 768px) 100vw, 33vw"
/>
))}
</div>
);
}This project is licensed under the MIT License - see the LICENSE file for details.
Made with love by Mona Aghili