The Image Component
The <Image /> component is Astro’s built-in answer to image optimization. Instead of shipping raw, oversized files and writing fragile <img> markup by hand, you import an image and let Astro transform it at build time: it converts to modern formats like WebP and AVIF, generates correctly sized files, and emits markup that prevents layout shift. It lives in the astro:assets module and works for both local files and remote URLs, all with zero client-side JavaScript.
Importing and basic usage
<Image /> is imported from astro:assets, a virtual module that ships with Astro. For local images, you also import the image itself as an ES module — this gives Astro the metadata (intrinsic width, height, format) it needs to optimize the file.
---
import { Image } from "astro:assets";
import rocket from "../assets/rocket.png";
---
<Image src={rocket} alt="A rocket launching into orbit" />
Because you imported rocket, Astro already knows its dimensions and can infer width and height automatically. The generated <img> includes those attributes plus loading="lazy" and decoding="async" by default, so images below the fold don’t block rendering.
The
altattribute is required on<Image />. If the image is purely decorative, pass an empty string (alt="") — omitting it entirely is a build error. This enforces accessibility by default.
Required and core attributes
| Attribute | Required | Description |
|---|---|---|
src | Yes | An imported image, an import path, or a remote URL string. |
alt | Yes | Alternative text; use "" for decorative images. |
width / height | For remote/inline | Inferred automatically for imported local images. |
format | No | Output format: webp (default), avif, png, jpeg, svg. |
quality | No | low, mid, high, max, or a number 0–100. |
densities | No | Pixel densities for the srcset (e.g. [1.5, 2]). |
widths | No | Explicit widths for a responsive srcset. |
loading | No | lazy (default) or eager for above-the-fold images. |
Resizing and format control
You rarely want to serve an image at its full intrinsic resolution. Pass width (and optionally height) to downscale; Astro preserves the aspect ratio when only one is given. You can also force an output format and tune quality.
---
import { Image } from "astro:assets";
import hero from "../assets/hero.jpg";
---
<Image
src={hero}
alt="Mountain landscape at dawn"
width={800}
format="avif"
quality="high"
/>
Here a large JPEG is resized to 800px wide and re-encoded as AVIF at high quality. Astro writes the optimized file into the build output and rewrites src to point at it. Importantly, Astro will never upscale a local image beyond its intrinsic dimensions — requesting a width larger than the source simply yields the original size.
Optimizing for high-density displays
To serve sharper images on Retina-class screens, use densities. Astro generates a srcset with the requested pixel ratios so browsers pick the right file.
---
import { Image } from "astro:assets";
import avatar from "../assets/avatar.png";
---
<Image src={avatar} alt="User avatar" width={120} densities={[1.5, 2]} />
This produces three candidate sources (1x, 1.5x, 2x) at 120, 180, and 240 CSS pixels respectively, letting high-DPI devices fetch crisper assets while standard displays download the smaller file.
Remote images
You can pass a URL string to src, but Astro needs explicit width and height because it cannot read remote files at build time to infer them. By default Astro only optimizes images from your own domain — to optimize images from other hosts you must allow them in your config.
// astro.config.mjs
import { defineConfig } from "astro/config";
export default defineConfig({
image: {
domains: ["images.unsplash.com"],
// or use remotePatterns for wildcard matching
remotePatterns: [{ protocol: "https" }],
},
});
---
import { Image } from "astro:assets";
---
<Image
src="https://images.unsplash.com/photo-123"
alt="Remote photo"
width={600}
height={400}
/>
How optimization works
By default, image processing uses Sharp, a fast native library. In static (SSG) mode, every transform runs once at build time and the results are emitted as hashed files. In server (SSR) mode, Astro serves optimized images on demand through an endpoint. You can inspect what happened by building locally.
npm run build
Output:
▶ src/pages/index.astro
└─ /_astro/hero.Ck3p9d.avif (image) (+1)
generating optimized images
▶ /_astro/hero.Ck3p9d.avif
└─ Completed in 84ms.
Astro stores optimized images under
/_astro/with content-hashed filenames, which makes them safe to cache forever. The hash changes only when the source or transform options change.
Best Practices
- Always provide meaningful
alttext; usealt=""only for genuinely decorative images. - Set
loading="eager"on your largest above-the-fold image (the LCP element) and leave the rest lazy. - Prefer importing local images so Astro can infer dimensions and prevent cumulative layout shift.
- Use
format="avif"orwebpfor photographs to cut file size dramatically over PNG/JPEG. - Add remote hosts to
image.domainsorremotePatternsdeliberately — don’t open it wider than you need. - Specify
widthto the size you actually render, not the source’s full resolution, to avoid shipping oversized files. - Reach for
<Picture />instead when you need multiple<source>formats with explicit fallbacks.