Media & time
Image
An image with the box reserved, a loading state, and a failure state.
Import
import { Image } from '@the_viveksingh/vivek-ui'Ratios and shapes
ratio reserves the box before the file arrives, which is what stops the page jumping as images load.
<Image src="/hero.jpg" alt="A wide landscape" ratio={16 / 9} />
<Image src="/team.jpg" alt="The team" ratio={1} />
<Image src="/avatar.jpg" alt="Vivek" ratio={1} rounded="full" />When the image fails
A dead URL renders the fallback rather than the browser broken-image icon, and the alt text stays reachable.

A dead URL renders the fallback, not the browser's broken-image icon. The alt text stays in the accessibility tree, so the description is not lost with the picture.
<Image
src="/missing.jpg"
alt="A photograph of the Bengaluru office"
ratio={4 / 3}
fallback="Image unavailable"
/>With a caption
A caption renders a real figure and figcaption.
<Image
src="/artwork.jpg"
alt="Abstract gradient artwork"
ratio={16 / 9}
caption="Photo: Vivek Kumar Singh"
/>Props
Generated from the package's own type declarations, so this table cannot drift from the code.
| Prop | Type | Default | Description |
|---|---|---|---|
src required | string | — | — |
alt required | string | — | Required, and deliberately not optional. An image with no `alt` is announced by reading out its filename, which is worse than silence. Pass `alt=""` for a decorative image — that is an explicit statement that it carries no information, and it is the right answer surprisingly often. Making the decision impossible to skip is the point; it is the same reason `IconButton` requires `aria-label`. |
ratio | number | — | Aspect ratio as width / height, e.g. `16 / 9`. Reserving the box before the image loads is what prevents the page jumping as images arrive — the single largest contributor to a poor Cumulative Layout Shift score. |
fit | 'cover' | 'contain' | 'fill' | 'none' | — | How the image fills its box once a `ratio` is set. Default `cover`. |
position | string | — | Focal point for `cover`, e.g. `'top'` so faces are not cropped out. |
rounded | 'none' | 'sm' | 'md' | 'lg' | 'full' | — | — |
fallback | ReactNode | — | Shown while loading, and instead of the image if it fails. A broken image icon is the worst possible outcome on a marketing page, and images fail for reasons the author cannot control — a dead CDN, an ad blocker, a corporate proxy. |
caption | ReactNode | — | Renders `<figure>` with a `<figcaption>` rather than a bare `<img>`. |
loading | 'lazy' | 'eager' | — | Default `lazy`. Set `eager` for anything above the fold — a lazily-loaded hero image is slower, because the browser will not start fetching it until layout says it is visible. |
Every remaining prop is spread onto the root element, so all standard HTML and ARIA attributes work. className and style are merged with the library's own, never replaced, and the ref forwards to the root DOM node.
Rendering
Image declares 'use client' because it needs state, effects or event handlers. Importing it into a Server Component creates a client boundary at this component — everything above it stays on the server.