tw-next-image
v1.0.0
Published
Tailwind-first Next.js Image component with automatic sizes inference.
Maintainers
Readme
tw-next-image
Tailwind-first Next.js image component with automatic sizes inference.
See DOCS.md for full examples and API reference.
Why
The next/image component requires a sizes attribute to serve optimally-sized images. Without it,
Next.js defaults to 100vw—meaning a 64px thumbnail requests the same massive image as a full-width hero. This wastes
bandwidth and hurts Core Web Vitals.
The problem: crafting sizes by hand is tedious. Every responsive image needs a media query string that mirrors your
CSS breakpoints:
// Manual sizes for a responsive image 😴
<Image src="/avatar.webp" sizes="(min-width: 1024px) 120px, 100px" className="size-25 lg:size-30" />tw-next-image eliminates this busywork. It parses your Tailwind classes and infers the correct sizes
automatically:
// Same result, zero mental overhead 🎉
<SmartImage src="/avatar.webp" className="size-25 lg:size-30" />
// → sizes="(min-width: 1024px) 120px, 100px"- next/image responsive behavior discussion
- Tailwind + next/image integration request
- Inefficient srcset generation issue
- Deep dive: the sizes attribute in Next.js
📦 Install
npm install tw-next-image
# or
pnpm add tw-next-image
# or
yarn add tw-next-image
# or
bun add tw-next-imageRequirements: Next.js ≥13, React ≥18
🚀 Quick Start
import { SmartImage } from "tw-next-image";
// sizes inferred from className
<SmartImage src="/logo.png" className="size-11" />
// → sizes="44px"
// Responsive breakpoints
<SmartImage src="/avatar.webp" className="size-25 lg:size-30" />
// → sizes="(min-width: 1024px) 120px, 100px"SmartImage wraps next/image with fill mode—ensure the wrapper has height via size-*, h-*, aspect-*, or
inline styles.
🔧 Custom tailwind-merge
If your app uses a custom tailwind-merge config, inject it via createSmartImage:
import { createSmartImage } from "tw-next-image";
import { customTwMerge } from "./tailwind/merge";
export const SmartImage = createSmartImage({ cx: customTwMerge });📖 Standalone Inference
Use inferImageSizes without the React component:
import { inferImageSizes } from "tw-next-image/infer-sizes";
inferImageSizes({ className: "w-75" });
// → "300px"
inferImageSizes({ className: "size-25 lg:size-30" });
// → "(min-width: 1024px) 120px, 100px"