Expoexpo-image-pickerImage UploadReact Native

How to Pick Images and Videos in Expo (expo-image-picker Guide)

Add a photo/video picker to your Expo app with expo-image-picker — request permissions, open the library or camera, crop, allow multiple selection, and upload the result. SDK 54+ examples.

DeveloperMill2 min read

Almost every app eventually needs a way to pick a profile photo, attach an image, or upload a video. expo-image-picker opens the system's native media UI so users can choose from their library or shoot something new — and it's consistently one of the most-searched Expo modules. Here's how to use it end-to-end.

Install

npx expo install expo-image-picker

Add permission copy via the config plugin in app.json:

{
  "expo": {
    "plugins": [
      ["expo-image-picker", {
        "photosPermission": "Allow $(PRODUCT_NAME) to access your photos."
      }]
    ]
  }
}

Pick an image from the library

import * as ImagePicker from "expo-image-picker"
import { useState } from "react"
import { Button, Image, View } from "react-native"

export default function Picker() {
  const [uri, setUri] = useState<string | null>(null)

  async function pick() {
    const result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ["images"],
      allowsEditing: true,
      aspect: [1, 1],
      quality: 0.8,
    })

    if (!result.canceled) {
      setUri(result.assets[0].uri)
    }
  }

  return (
    <View style={{ gap: 12, padding: 24 }}>
      <Button title="Pick a photo" onPress={pick} />
      {uri && <Image source={{ uri }} style={{ width: 200, height: 200, borderRadius: 12 }} />}
    </View>
  )
}

Note the modern API uses mediaTypes: ["images"] (an array of strings) — the old MediaTypeOptions enum is deprecated.

Take a new photo instead

Same options, but launch the camera:

const result = await ImagePicker.launchCameraAsync({
  mediaTypes: ["images"],
  quality: 0.8,
})

launchCameraAsync requires camera permission — request it first with ImagePicker.requestCameraPermissionsAsync().

Allow multiple selection

const result = await ImagePicker.launchImageLibraryAsync({
  mediaTypes: ["images", "videos"],
  allowsMultipleSelection: true,
  selectionLimit: 5,
})

// result.assets is now an array of everything the user picked

Upload the picked file

Turn the asset into FormData and POST it:

async function upload(uri: string) {
  const form = new FormData()
  form.append("file", {
    uri,
    name: "upload.jpg",
    type: "image/jpeg",
  } as any)

  await fetch("https://your-api.com/upload", { method: "POST", body: form })
}

Gotchas

  • Always check result.canceled before touching result.assets — the user may back out.
  • quality is 0–1; lower it to shrink upload sizes.
  • To render picked images faster in long lists, swap React Native's Image for expo-image.

Next steps

Want to capture instead of pick? See the expo-camera tutorial. To store uploaded file references offline, check expo-sqlite or the full top 10 Expo SDK modules.

Frequently asked questions

How do I let users pick an image from their library in Expo?

Install expo-image-picker and call `ImagePicker.launchImageLibraryAsync({ mediaTypes: ['images'] })`. If the user doesn't cancel, the result's `assets[0].uri` is the selected image's local URI.

How do I upload the picked image to a server?

Build a FormData object with the asset's uri, name, and type, then POST it with fetch. For Supabase or S3 you can upload the file directly from the uri returned by the picker.

How do I allow selecting multiple images?

Pass `allowsMultipleSelection: true` to `launchImageLibraryAsync`. The result's `assets` array then contains every selected item instead of just one.

Build it faster with a template

Production-ready Expo React Native templates with the patterns from this post already wired up.

Browse templates