Every project has that moment where image components start looking almost identical.
You keep adding the same props like responsive, placeholder="blur", retry, or transition over and over again. It works, but it also means updating image behavior later becomes repetitive.
While working on React Smart Image, I wanted a simpler way to keep image settings consistent across a project without creating wrapper components for every use case. That's why I added two features: SmartImageProvider and Image Presets.
The repetitive props problem
This is probably familiar.
<SmartImage
src="/shoe-1.jpg"
responsive
placeholder="blur"
retry={2}
transition="fade"
/>
<SmartImage
src="/shoe-2.jpg"
responsive
placeholder="blur"
retry={2}
transition="fade"
/>
Nothing is wrong with this approach.
But when you have dozens of images, changing one shared setting means touching every component.
SmartImageProvider
SmartImageProvider lets you define default settings once and automatically apply them to every SmartImage inside your application.
Instead of repeating props everywhere, wrap your app once.
import { SmartImageProvider } from "@concatstring/react-smart-image";
function App() {
return (
<SmartImageProvider
defaults={{
responsive: true,
retry: 2,
placeholder: "blur",
transition: "fade",
}}
>
<AppRoutes />
</SmartImageProvider>
);
}
Now your image component becomes much cleaner.
<SmartImage
src="/shoe.jpg"
alt="Running Shoe"
/>
It still gets responsive loading, blur placeholders, retry handling, and transitions from the provider automatically.
Need different behavior for one image?
Component props still override the defaults.
<SmartImage
src="/hero.jpg"
priority
transition="scale"
/>
That flexibility makes it easy to keep global consistency while handling special cases.
Image Presets
After adding global defaults, I noticed another pattern.
Different types of images usually need different configurations.
Hero banners should load with priority.
Product images should support zoom.
User avatars should have fixed dimensions and skeleton loading.
Instead of remembering those combinations every time, I added Image Presets.
import { createImagePresets } from "@concatstring/react-smart-image";
const presets = createImagePresets({
hero: {
priority: true,
responsive: true,
transition: "fade",
},
product: {
zoom: true,
responsive: true,
placeholder: "blur",
},
avatar: {
width: 60,
height: 60,
skeleton: true,
},
});
Now using them is much simpler.
<SmartImage preset="hero" src="/hero.jpg" />
<SmartImage preset="product" src="/shoe.jpg" />
<SmartImage preset="avatar" src="/user.jpg" />
One preset replaces several repeated props while keeping everything consistent.
Using both together
The best part is that these features work together.
<SmartImageProvider
defaults={{ retry: 2 }}
presets={presets}
>
<App />
</SmartImageProvider>
When a product image renders, it combines:
Provider defaults
Product preset settings
Component-specific props
The priority order is simple:
Component Props → Preset → Provider Defaults → Library Defaults.
Why I built it this way
My first thought was to create separate components like HeroImage, ProductImage, and AvatarImage.
But that quickly turns into more components to maintain.
Keeping everything inside a single SmartImage component felt much cleaner. Now, if I want every product image to retry failed requests or every hero image to use a different transition, I only need to update one place.
Final thoughts
These aren't massive features, but they've made day-to-day development much smoother for me.
Less repetitive code, more consistent image behavior, and fewer places to update when requirements change. If you're already using Smart Image, SmartImageProvider and Image Presets are worth trying together—they've become my default setup for handling images across a project.
Resources
Website: https://labs.concatstring.com/products/react-smart-image
GitHub Source Code: https://github.com/concatstring-account/react-smart-image
NPM: https://www.npmjs.com/package/@concatstring/react-smart-image
Live Demo: https://react-smart-image.netlify.app/

Top comments (0)