HomeGuidesReferenceLearn

Reference version

ArchiveExpo SnackDiscord and ForumsNewsletter

Expo Image iconExpo Image

GitHub

npm

A cross-platform and performant React component that loads and renders images.


expo-image is a cross-platform React component that loads and renders images.

Main features:

Platform Compatibility

Android DeviceAndroid EmulatoriOS DeviceiOS SimulatorWeb

Supported image formats

FormatAndroidiOSWeb
WebP ~96% adoption
PNG / APNG / ~96% adoption
AVIF (No support for animated AVIFs) ~79% adoption
HEIC not adopted yet
JPEG
GIF
SVG
ICO
ICNS

Installation

expo-image is not yet available in Snack.
Terminal
- npx expo install expo-image

If you're installing this in a bare React Native app, you should also follow these additional installation instructions.

Usage

import { Image } from 'expo-image';
import { StyleSheet, View } from 'react-native';

const blurhash =
  '|rF?hV%2WCj[ayj[a|j[az_NaeWBj@ayfRayfQfQM{M|azj[azf6fQfQfQIpWXofj[ayj[j[fQayWCoeoeaya}j[ayfQa{oLj?j[WVj[ayayj[fQoff7azayj[ayj[j[ayofayayayj[fQj[ayayj[ayfjj[j[ayjuayj[';

export default function App() {
  return (
    <View style={styles.container}>
      <Image
        style={styles.image}
        source="https://picsum.photos/seed/696/3000/2000"
        placeholder={blurhash}
        contentFit="cover"
        transition={1000}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  image: {
    flex: 1,
    width: '100%',
    backgroundColor: '#0553',
  },
});

API

import { Image } from 'expo-image';

Component

Image

Type: React.PureComponent<ImageProps>

Props

Only for: 
Android
iOS

accessibilityLabel

Optional • Type: string • Default: undefined

The text that's read by the screen reader when the user interacts with the image.

Only for: 
Android
iOS

accessible

Optional • Type: boolean • Default: false

When true, indicates that the view is an accessibility element. When a view is an accessibility element, it groups its children into a single selectable component.

On Android, the accessible property will be translated into the native isScreenReaderFocusable, so it's only affecting the screen readers behaviour.

blurRadius

Optional • Type: number • Default: 0

The radius of the blur in points, 0 means no blur effect. This effect is not applied to placeholders.

cachePolicy

Optional • Type: null | 'none' | 'disk' | 'memory' | 'memory-disk' • Default: 'disk'

Determines whether to cache the image and where: on the disk, in the memory or both.

  • 'none' - Image is not cached at all.

  • 'disk' - Image is queried from the disk cache if exists, otherwise it's downloaded and then stored on the disk.

  • 'memory' - Image is cached in memory. Might be useful when you render a high-resolution picture many times. Memory cache may be purged very quickly to prevent high memory usage and the risk of out of memory exceptions.

  • 'memory-disk' - Image is cached in memory, but with a fallback to the disk cache.

contentFit

Optional • Type: ImageContentFit • Default: 'cover'

Determines how the image should be resized to fit its container. This property tells the image to fill the container in a variety of ways; such as "preserve that aspect ratio" or "stretch up and take up as much space as possible". It mirrors the CSS object-fit property.

  • 'cover' - The image is sized to maintain its aspect ratio while filling the container box. If the image's aspect ratio does not match the aspect ratio of its box, then the object will be clipped to fit.

  • 'contain' - The image is scaled down or up to maintain its aspect ratio while fitting within the container box.

  • 'fill' - The image is sized to entirely fill the container box. If necessary, the image will be stretched or squished to fit.

  • 'none' - The image is not resized and is centered by default. When specified, the exact position can be controlled with contentPosition prop.

  • 'scale-down' - The image is sized as if none or contain were specified, whichever would result in a smaller concrete image size.

contentPosition

Optional • Type: ImageContentPosition • Default: 'center'

It is used together with contentFit to specify how the image should be positioned with x/y coordinates inside its own container. An equivalent of the CSS object-position property.

Deprecated. Provides compatibility for defaultSource from React Native Image. Use placeholder prop instead.

defaultSource

Optional • Type: null | ImageSource

Only for: 
iOS 16.0+

enableLiveTextInteraction

Optional • Type: boolean • Default: false

Enables Live Text interaction with the image. Check official Apple documentation for more details.

Deprecated. Provides compatibility for fadeDuration from React Native Image. Instead use transition with the provided duration.

fadeDuration

Optional • Type: number

Only for: 
Android

focusable

Optional • Type: boolean • Default: false

Whether this View should be focusable with a non-touch input device and receive focus with a hardware keyboard.

Deprecated. Provides compatibility for loadingIndicatorSource from React Native Image. Use placeholder prop instead.

loadingIndicatorSource

Optional • Type: null | ImageSource

onError

Optional • Type: (event: ImageErrorEventData) => void

Called on an image fetching error.

onLoad

Optional • Type: (event: ImageLoadEventData) => void

Called when the image load completes successfully.

onLoadEnd

Optional • Type: () => void

Called when the image load either succeeds or fails.

onLoadStart

Optional • Type: () => void

Called when the image starts to load.

onProgress

Optional • Type: (event: ImageProgressEventData) => void

Called when the image is loading. Can be called multiple times before the image has finished loading. The event object provides details on how many bytes were loaded so far and what's the expected total size.

placeholder

Optional • Type: null | string | number | string[] | ImageSource | ImageSource[]

An image to display while loading the proper image and no image has been displayed yet or the source is unset.

priority

Optional • Type: null | 'low' | 'normal' | 'high' • Default: 'normal'

Priorities for completing loads. If more than one load is queued at a time, the load with the higher priority will be started first. Priorities are considered best effort, there are no guarantees about the order in which loads will start or finish.

Only for: 
Android
iOS

recyclingKey

Optional • Type: null | string • Default: null

Changing this prop resets the image view content to blank or a placeholder before loading and rendering the final image. This is especially useful for any kinds of recycling views like FlashList to prevent showing the previous source before the new one fully loads.

Deprecated. Provides compatibility for resizeMode from React Native Image. Note that "repeat" option is not supported at all. Use the more powerful contentFit and contentPosition props instead.

resizeMode

Optional • Type: 'cover' | 'contain' | 'center' | 'stretch' | 'repeat'

Only for: 
Web

responsivePolicy

Optional • Type: 'live' | 'initial' • Default: "live"

Determines whether to choose image source based on container size only on mount or on every resize. Use initial to improve performance.

source

Optional • Type: null | string | number | string[] | ImageSource | ImageSource[]

The image source, either a remote URL, a local file resource or a number that is the result of the require() function. When provided as an array of sources, the source that fits best into the container size and is closest to the screen scale will be chosen. In this case it is important to provide width, height and scale properties.

Only for: 
Android
iOS

tintColor

Optional • Type: null | string • Default: null

A color used to tint template images (a bitmap image where only the opacity matters). The color is applied to every non-transparent pixel, causing the image’s shape to adopt that color. This effect is not applied to placeholders.

transition

Optional • Type: null | number | ImageTransition

Describes how the image view should transition the contents when switching the image source.
If provided as a number, it is the duration in milliseconds of the 'cross-dissolve' effect.

Inherited Props

Static Methods

clearDiskCache()

Asynchronously clears all images from the disk cache.

Returns

  • Promise<boolean>

A promise resolving to true when the operation succeeds. It may resolve to false on Android when the activity is no longer available.

clearMemoryCache()

Asynchronously clears all images stored in memory.

Returns

  • Promise<boolean>

A promise resolving to true when the operation succeeds. It may resolve to false on Android when the activity is no longer available.

prefetch(urls)

NameTypeDescription
urlsstring | string[]-

Preloads images at the given urls that can be later used in the image view. Preloaded images are always cached on the disk, so make sure to use disk (default) or memory-disk cache policy.

Returns

  • void

Types

ImageContentPosition

Specifies the position of the image inside its container. One value controls the x-axis and the second value controls the y-axis.

Additionally, it supports stringified shorthand form that specifies the edges to which to align the image content:
'center', 'top', 'right', 'bottom', 'left', 'top center', 'top right', 'top left', 'right center', 'right top', 'right bottom', 'bottom center', 'bottom right', 'bottom left', 'left center', 'left top', 'left bottom'.
If only one keyword is provided, then the other dimension is set to 'center' ('50%'), so the image is placed in the middle of the specified edge.
As an example, 'top right' is the same as { top: 0, right: 0 } and 'bottom' is the same as { bottom: 0, left: '50%' }.

ImageContentPositionString or object shaped as below:


NameTypeDescription
right
(optional)
ImageContentPositionValue-
top
(optional)
ImageContentPositionValue-

NameTypeDescription
left
(optional)
ImageContentPositionValue-
top
(optional)
ImageContentPositionValue-

NameTypeDescription
bottom
(optional)
ImageContentPositionValue-
right
(optional)
ImageContentPositionValue-

NameTypeDescription
bottom
(optional)
ImageContentPositionValue-
left
(optional)
ImageContentPositionValue-

ImageContentPositionValue

Literal Type: multiple types

A value that represents the relative position of a single axis.

If number, it is a distance in points (logical pixels) from the respective edge.
If string, it must be a percentage value where '100%' is the difference in size between the container and the image along the respective axis, or 'center' which is an alias for '50%' that is the default value. You can read more regarding percentages on the MDN docs for background-position that describes this concept well.

Acceptable values are: number | string | 'center'

ImageErrorEventData

NameTypeDescription
errorstring-

ImageLoadEventData

NameTypeDescription
cacheType'none' | 'disk' | 'memory'-
source{ height: number, mediaType: string | null, url: string, width: number }-

ImageProgressEventData

NameTypeDescription
loadednumber-
totalnumber-

ImageSource

NameTypeDescription
blurhash
(optional)
string

The blurhash string to use to generate the image. You can read more about the blurhash on woltapp/blurhash repo. Ignored when uri is provided. When using the blurhash, you should also provide width and height (higher values reduce performance), otherwise their default value is 16.

cacheKey
(optional)
string

The cache key used to query and store this specific image. If not provided, the uri is used also as the cache key.

headers
(optional)
Record<string, string>Only for: 
Android
iOS

An object representing the HTTP headers to send along with the request for a remote image.

height
(optional)
number

Can be specified if known at build time, in which case the value will be used to set the default <Image/> component dimension

uri
(optional)
string

A string representing the resource identifier for the image, which could be an http address, a local file path, or the name of a static image resource.

width
(optional)
number

Can be specified if known at build time, in which case the value will be used to set the default <Image/> component dimension

ImageTransition

An object that describes the smooth transition when switching the image source.

NameTypeDescription
duration
(optional)
number

The duration of the transition in milliseconds.

Default: 0
effect
(optional)
'cross-dissolve' | 'flip-from-top' | 'flip-from-right' | 'flip-from-bottom' | 'flip-from-left' | 'curl-up' | 'curl-down' | null

An animation effect used for transition.

Default: 'cross-dissolve' On Android, only `'cross-dissolve'` is supported. On Web, `'curl-up'` and `'curl-down'` effects are not supported.
timing
(optional)
'ease-in-out' | 'ease-in' | 'ease-out' | 'linear'

Specifies the speed curve of the transition effect and how intermediate values are calculated.

Default: 'ease-in-out'

Generating a blurhash on a server

Images can significantly improve the visual experience, however, they can also slow down app/page loading times due to their large file sizes. To overcome this, you can create placeholder images using blurhash algorithm that provides an immersive experience while deferring the loading of the actual picture until later.

This guide demonstrates how to create a blurhash of an uploaded image on the backend using JavaScript and Express.js. The same techniques and principles apply to other languages and server technologies.

Start by installing a few dependencies: multer for handling multipart requests, sharp for converting files to a data buffer, and the official blurhash JavaScript package.

Terminal
- npm install multer sharp blurhash

Next, import all required functions from installed packages and initialize multer:

// Multer is a middleware for handling `multipart/form-data`.
const multer = require('multer');
// Sharp allows you to receive a data buffer from the uploaded image.
const sharp = require('sharp');
// Import the encode function from the blurhash package.
const { encode } = require('blurhash');

// Initialize `multer`.
const upload = multer();

Assuming the app is a variable that holds a reference to the Express server, an endpoint can be created that accepts an image and returns a JSON response containing the generated blurhash.

app.post('/blurhash', upload.single('image'), async (req, res) => {
  const { file } = req;
  // If the file is not available we're returning with error.
  if (file === null) {
    res.status(400).json({ message: 'Image is missing' });
    return;
  }

  // Users can specify number of components in each axes.
  const componentX = req.body.componentX ?? 4;
  const componentY = req.body.componentY ?? 3;

  // We're converting provided image to a byte buffer.
  // Sharp currently supports multiple common formats like JPEG, PNG, WebP, GIF, and AVIF.
  const { data, info } = await sharp(file.buffer).ensureAlpha().raw().toBuffer({
    resolveWithObject: true,
  });

  const blurhash = encode(data, info.width, info.height, componentX, componentY);
  res.json({ blurhash });
});

Additionally, the request can include two parameters: componentX and componentY, are passed through the algorithm. These values can be calculated or hard-coded on the server or specified by the user. However, they must be within the range of 1 to 9 and have an aspect ratio similar to the uploaded image. A value of 9 will give the best results but may take longer to generate the hash.

The process of generating a blurhash can be accomplished in various languages and server technologies, similar to the one using JavaScript. The key step is to locate an encoder for your chosen language, which can often be found in the woltapp/blurhash repository. Once you have the encoder, you will need to obtain a representation of the image. Some libraries use a default image class (for example, the Swift implementation uses UIImage). In other cases, you will have to provide raw byte data. Make sure to check the encoder's documentation to confirm the expected data format.

When working with raw byte data, ensure that the alpha layer is present (each pixel is represented by red, green, blue, and alpha values). Failing to do so will lead to errors such as "width and height must match the pixels array".