This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.

Expo Expo iconExpo

Set of common methods and types for Expo and related packages.

Android
iOS
tvOS
Web
Included in Expo Go

Installation

Terminal
- npx expo install expo
- yarn expo install expo
- pnpm expo install expo
- bun expo install expo

API

import * as Expo from 'expo';

expo/fetch API

expo/fetch provides a WinterCG-compliant Fetch API that works consistently across web and mobile environments, ensuring a standardized and cross-platform fetch experience within Expo applications.

Streaming fetch
import { fetch } from 'expo/fetch'; const resp = await fetch('https://httpbin.org/drip?numbytes=512&duration=2', { headers: { Accept: 'text/event-stream' }, }); const reader = resp.body.getReader(); const chunks = []; while (true) { const { done, value } = await reader.read(); if (done) { break; } chunks.push(value); } const buffer = new Uint8Array(chunks.reduce((acc, chunk) => acc + chunk.length, 0)); console.log(buffer.length); // 512

Encoding APIs

TextEncoder and TextDecoder are built-in APIs that provide a way to encode and decode text in various character encodings. They are available on all platforms. Refer to the browser and server runtime support for web and Node.js.

TextEncoder and TextDecoder
// [104, 101, 108, 108, 111] const hello = new TextEncoder().encode('hello'); // "hello" const text = new TextDecoder().decode(hello);

The TextEncoder API is included in the Hermes engine. See the source code in TextEncoder.cpp inside the Hermes GitHub repository.

The TextDecoder API is not spec-compliant on native platforms. Only the UTF-8 encoding is supported. If you need support for more encodings, use a polyfill like text-encoding.

The stream equivalents of these APIs, TextEncoderStream and TextDecoderStream, are also available on all platforms. They allow you to encode and decode text in a streaming manner, which is useful for processing large amounts of data without loading it all into memory at once.

TextEncoderStream
const encoder = new TextEncoderStream(); const stream = new ReadableStream({ start(controller) { controller.enqueue('Hello'); controller.enqueue('World'); controller.close(); }, }); const reader = stream.pipeThrough(encoder).getReader(); reader.read().then(({ done, value }) => { console.log(value); // Uint8Array [72, 101, 108, 108, 111] });

Streams API

Global support for standard web streams is available on native platforms to match the behavior of web and server platforms. Refer to the browser and server runtime support for specific web and Node.js support. EAS Hosting server runtime also includes support for the standard web streams API.

Globally access ReadableStream, WritableStream, and TransformStream classes.

ReadableStream
const stream = new ReadableStream({ start(controller) { controller.enqueue('Hello'); controller.enqueue('World'); controller.close(); }, }); const reader = stream.getReader(); reader.read().then(({ done, value }) => { console.log(value); // Hello }); reader.read().then(({ done, value }) => { console.log(value); // World });

URL API

URL provides the standard API on all platforms.

On native platforms, built-in URL and URLSearchParams implementations replace the shims in react-native. Refer to the browser and server runtime support for web and Node.js.

URL and URLSearchParams
const url = new URL('https://expo.dev'); const params = new URLSearchParams();

Expo's built-in URL support attempts to be fully spec compliant. The only missing exception is that native platforms do not currently support non-ASCII characters in the hostname.

Non-ASCII characters
console.log(new URL('http://🥓').toString()); // This outputs the following: // - Web, Node.js: http://xn--pr9h/ // - Android, iOS: http://🥓/

structuredClone

structuredClone is a built-in function that allows you to create a deep copy of a value, including complex objects like Map, Set, and ArrayBuffer. It is available on all platforms.

const original = { name: 'Expo', date: new Date() }; const clone = structuredClone(original); console.log(clone); // { name: 'Expo', date: Date }

The transfer option for ArrayBuffer and TypedArrays is not implemented.

Remove any custom polyfills for structuredClone to prevent bloat. Refer to the standard documentation for more information on the structured clone algorithm.

No API data file found, sorry!

Common questions

Some common questions about using the expo package in your project.

rootRegisterComponent setup for existing React Native projects

If you are managing your React Native project's native directories (android and ios) manually, you need to follow the instructions below to set up the registerRootComponent function. This is necessary for the Expo modules to work correctly.

Android

Update the android/app/src/main/your-package/MainActivity.java file to use the name main in the getMainComponentName function.

android/app/src/main/your-package/MainActivity.java
@Override protected String getMainComponentName() { + return "main"; }

iOS

Update the iOS ios/your-project/AppDelegate.(m|mm|swift) file to use the moduleName main in the createRootViewWithBridge:bridge moduleName:@"main" initialProperties:initProps line of the application:didFinishLaunchingWithOptions: function.

What if I want to name my main app file something other than App.js or app/_layout.tsx?

For projects that do not use Expo Router, you can set the "main" in package.json to any file within your project. If you do this, then you need to use registerRootComponent. The export default will not make this component the root for the app if you are using a custom entry file.

For example, let's say you want to make src/main.jsx the entry file for your app — maybe you don't like having JavaScript files in the project root. First, set this in package.json:

package.json
{ "main": "src/main.jsx" }

Then, in src/main.jsx, make sure you call registerRootComponent and pass in the component you want to render at the root of the app:

src/main.jsx
import { registerRootComponent } from 'expo'; import { View } from 'react-native'; function App() { return <View />; } registerRootComponent(App);

For projects that use Expo Router, you can create a custom entry point by following these steps from Expo Router's installation guide. To use the top-level src directory in your Expo Router project, see src directory reference for more information.