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 - No external dependencies, tree-shakeable
- 🚀 Performance - Optimized for Core Web Vitals and page speed
- 🔒 Privacy Safe - No environment detection or data collection
bun add react-optimized-image
npm install react-optimized-image
yarn add react-optimized-image
pnpm add react-optimized-image
import { Image } from "react-optimized-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-optimized-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..."
/>
Get helpful warnings during development:
import { configureImage } from "react-optimized-image";
// Enable warnings during development
if (process.env.NODE_ENV === "development") {
configureImage({ enableWarnings: true });
}
Integrate with your preferred CDN or image service:
import { Image, ImageLoader } from "react-optimized-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
width
andheight
to 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
priority
for above-the-fold images -
Leverage responsive images: Use the
sizes
prop 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>
);
}
Feature | react-optimized-image | Next.js Image | react-image | img tag |
---|---|---|---|---|
Bundle Size | 🟢 Tiny (~8kb) | 🟡 Large | 🟢 Small | 🟢 None |
Framework Dependency | 🟢 React only | 🔴 Next.js required | 🟢 React only | 🟢 None |
Automatic Optimization | ✅ | ✅ | ❌ | ❌ |
Blur Placeholders | ✅ | ✅ | ❌ | ❌ |
TypeScript Support | ✅ | ✅ | ✅ | ✅ |
Lazy Loading | ✅ | ✅ | ✅ | ✅ (native) |
Custom Loaders | ✅ | ✅ | ❌ | ❌ |
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Made with ❤️ by Mona Aghili