code/tamagui.dev/data/docs/components/image/2.0.0.mdx
<Highlights features={[ 'Supports SSR.', 'Works on native and web.', 'Accepts Tamagui style props.', 'Pluggable architecture with createImage for expo-image and more.', ]} />
Image is already installed in tamagui, or you can install it independently:
npm install @tamagui/image
Use the src prop for the image URL:
import { Image } from 'tamagui'
export default () => (
<Image src="https://example.com/photo.jpg" width={200} height={200} />
)
You can also use objectFit to control how the image fits its container:
<Image src="https://example.com/photo.jpg" width="100%" height={300} objectFit="cover" />
width and height are Tamagui layout props. On native, they become React Native
Image styles. Remote images must resolve to a nonzero layout size, so use fixed
dimensions or place percentage-sized images inside a parent with defined dimensions:
<View width={320} height={200}>
<Image
src="https://example.com/photo.jpg"
width="100%"
height="100%"
objectFit="cover"
/>
</View>
Tamagui converts a string src to source={{ uri: src }} on native. Layout
dimensions stay in style; they are not copied into the native source metadata.
React Native source objects remain supported for migration, but src is preferred.
For better performance and features like blurhash placeholders and transitions,
you can use createImage to create a custom Image component with expo-image:
import { Image as ExpoImage } from 'expo-image'
import { createImage } from '@tamagui/image'
export const Image = createImage({
Component: ExpoImage,
resizeModePropName: 'contentFit',
objectPositionPropName: 'contentPosition',
})
Now you can use all expo-image props alongside Tamagui's unified API:
const blurhash = '|rF?hV%2WCj[ayj[a|j[az...'
export default () => (
<Image
src="https://example.com/photo.jpg"
width={200}
height={300}
objectFit="cover"
placeholder={{ blurhash }}
transition={300}
/>
)
<SimpleTable
headers={['Option', 'Type', 'Default', 'Description']}
rows={[
[
'Component',
'ComponentType',
'-',
'The underlying image component (expo-image, react-native-fast-image, etc.)',
],
[
'resizeModePropName',
'string',
"'resizeMode'",
"The prop name for resize mode. expo-image uses 'contentFit'",
],
[
'objectPositionPropName',
'string',
'undefined',
"The prop name for object position. expo-image uses 'contentPosition'",
],
[
'mapObjectFitToResizeMode',
'function',
'Default mapper',
"Custom function to map objectFit values to the component's resize mode",
],
[
'transformSource',
'function',
'Default transformer',
'Custom function to transform source props',
],
]}
/>
Always provide an alt attribute describing the image content. For decorative images, use an empty string (alt="").
// meaningful image
<Image
src="/team-photo.jpg"
alt="The Tamagui team at React Conf 2024"
width={400}
height={300}
/>
// decorative image
<Image
src="/decorative-bg.jpg"
alt=""
width={400}
height={300}
/>
On React Native, use accessible and accessibilityLabel for screen reader support. See the React Native Accessibility docs for details.
<Image
src="/avatar.jpg"
accessible
accessibilityLabel="User profile photo"
width={64}
height={64}
/>
Extends View with Tamagui props, plus:
<PropsTable
data={[
{
name: 'src',
type: 'string | number',
description:
'The image URL or native require() result. Preferred over source for better web alignment.',
},
{
name: 'alt',
type: 'string',
description:
'Alternative text describing the image for accessibility. Use empty string for decorative images.',
},
{
name: 'objectFit',
type: "'cover' | 'contain' | 'fill' | 'none' | 'scale-down'",
description:
'How the image should be resized to fit its container. Maps to CSS object-fit on web and resizeMode on native.',
},
{
name: 'objectPosition',
type: 'string',
description:
'How the image should be positioned within its container. On native, requires expo-image or similar for full support.',
},
{
name: 'source',
type: 'ImageSourcePropType',
description:
'Deprecated React Native source prop. It remains supported during migration; prefer src.',
},
{
name: 'resizeMode',
type: 'ImageResizeMode',
description: 'Deprecated. Use objectFit instead.',
},
]}
/>
These props pass through to the native `` element on web:
<PropsTable data={[ { name: 'loading', type: "'lazy' | 'eager'", description: 'Lazy load images below the fold. Use eager (default) for above-the-fold images.', }, { name: 'decoding', type: "'async' | 'sync' | 'auto'", description: 'Hint for how the browser should decode the image. Use async for non-blocking decode.', }, { name: 'fetchPriority', type: "'high' | 'low' | 'auto'", description: 'Hint for fetch priority. Use high for LCP (largest contentful paint) images.', }, { name: 'srcSet', type: 'string', description: 'Comma-separated list of image sources with width descriptors for responsive images.', }, { name: 'sizes', type: 'string', description: 'Media conditions describing the image display size, used with srcSet.', }, { name: 'crossOrigin', type: "'anonymous' | 'use-credentials'", description: 'CORS setting for the image request.', }, { name: 'referrerPolicy', type: 'string', description: 'Referrer policy for the image request.', }, ]} />
<PropsTable data={[ { name: 'alt', type: 'string', description: 'Alternative text for screen readers. Required for meaningful images, use empty string for decorative.', }, { name: 'accessible', type: 'boolean', description: 'Native only. Marks the image as an accessible element.', }, { name: 'accessibilityLabel', type: 'string', description: 'Native only. Label read by screen readers. Use with accessible={true}.', }, { name: 'aria-label', type: 'string', description: 'Overrides alt as the accessible name. Prefer using alt instead.', }, { name: 'aria-describedby', type: 'string', description: 'References an element providing extended description.', }, { name: 'aria-hidden', type: 'boolean', description: 'Hides the image from assistive technology. Alternative to alt="".', }, { name: 'role', type: 'string', description: "Set to 'presentation' or 'none' for decorative images, or 'img' (default).", }, ]} />
<Notice theme="green"> Web props like `loading`, `srcSet`, and `fetchPriority` only apply on web. On native, use expo-image via `createImage` for advanced features like blurhash placeholders and priority loading. </Notice>