Introduction
Next.js has built-in support for its own Image component via next/image. When you use it in place of the standard HTML <img> tag, Next.js automatically handles image optimisation, responsive sizing, and lazy loading — all without any extra configuration.
Basic Usage
In a page or component file, import and use the Image component directly:
import Image from 'next/image'
function Home() {
return (
<>
<h1>My Homepage</h1>
<Image
src="/me.png"
alt="Picture of the author"
width={500}
height={500}
/>
<p>Welcome to my homepage!</p>
</>
)
}
export default Home
The width and height props are required when using local or sized images. They tell Next.js the intrinsic dimensions, which helps it prevent Cumulative Layout Shift (CLS).
Usage in Markdown and MDX
If you're using a Next.js blog with MDX, the standard Markdown image syntax is automatically replaced by the Image component at build time. Assuming you have a file at public/static/images/ocean.jpg:

This renders an optimised image with automatic WebP conversion where supported.
You can also use the Image component directly inside MDX files:
<Image alt="ocean" src="/static/images/ocean.jpg" width={256} height={128} />
Note: If you save an image rendered via
next/image, it will be in WebP format if your browser supports it — resulting in significantly smaller file sizes than JPEG or PNG.
Benefits
Using next/image instead of a plain <img> tag gives you:
- Smaller file sizes — WebP format is typically ~30% smaller than equivalent JPEG
- Responsive images — Next.js automatically serves the right image size for the user's viewport using
srcset - Lazy loading — images below the fold load only when scrolled into view, improving initial page performance
- CLS prevention — space is reserved for the image before it loads, eliminating layout shift
- On-demand optimisation — images are optimised at request time rather than at build, so build times stay fast regardless of image count
Limitations
The next/image component has some important limitations to be aware of:
Vercel dependency
The image optimisation feature relies on a serverless function behind the scenes. If you're not hosting on Vercel, you'll need an external image CDN (like Cloudinary or Imgix) or you'll need to disable image optimisation. You can do this by removing the relevant remark plugin from your MDX configuration, or by setting unoptimized: true in your Next.js image config for static exports.
External images require allowlisting
Images loaded from external URLs are not optimised through next/image by default. You must explicitly allowlist external domains in next.config.js:
// next.config.js
module.exports = {
images: {
domains: ['images.unsplash.com', 'cdn.example.com'],
},
}
Public folder requirement
All locally stored images must be placed inside the public/ directory. The path you reference in src is relative to public/, so /static/images/photo.jpg maps to public/static/images/photo.jpg on disk.
Summary
For most Next.js projects, swapping <img> for <Image> is a straightforward win — you get better performance, smaller payloads, and CLS prevention with minimal effort. Just be aware of the Vercel dependency if you're deploying elsewhere, and allowlist any external image domains you need.
Tags