expo-file-system
@amazon-devices/expo-file-system provides access to file system of the device. It is also capable of downloading and uploading files from network URLs.
Installation
- Add the JavaScript library dependency in the package.jsonfile."dependencies": { ... "@amazon-devices/expo-file-system": "~2.0.0", "expo": "~50.0.0", ... }
- Reinstall dependencies using npm installcommand.
Examples
The example below demonstrates how to write text to a file.
import React, {useEffect, useState} from 'react';
import {Alert, Button, StyleSheet, Text, View} from 'react-native';
import * as FileSystem from '@amazon-devices/expo-file-system';
export const App = () => {
  const [fileContent, setFileContent] = useState<string | null>(null);
  const fileUri = FileSystem.documentDirectory + 'sample.txt';
  useEffect(() => {
    (async () => {
      const fileInfo = await FileSystem.getInfoAsync(fileUri);
      if (fileInfo.exists) {
        const content = await FileSystem.readAsStringAsync(fileUri);
        setFileContent(content);
      } else {
        setFileContent('File does not exist - you need to write to file');
      }
    })();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);
  const writeFile = async () => {
    try {
      await FileSystem.writeAsStringAsync(fileUri, 'Hello, file system!');
      Alert.alert('File written successfully!');
    } catch (error) {
      console.error('Error writing the file:', error);
    }
  };
  const readFile = async () => {
    try {
      const content = await FileSystem.readAsStringAsync(fileUri);
      setFileContent(content);
    } catch (error) {
      console.error('Error reading the file:', error);
    }
  };
  return (
    <View style={styles.container}>
      <Text style={styles.text}>File Content: {fileContent}</Text>
      <Button title="Write to File" onPress={writeFile} />
      <Button title="Read from File" onPress={readFile} />
    </View>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'white',
  },
  text: {
    fontSize: 30,
    textAlign: 'center',
  },
});
The example below demonstrates how to download or upload a file.
import * as FileSystem from '@amazon-devices/expo-file-system';
import {DownloadOptions, FileSystemUploadOptions} from '@amazon-devices/expo-file-system';
import React, {useState} from 'react';
import {Button, ScrollView, StyleSheet, Text, View} from 'react-native';
export const App = () => {
  const downloadAsyncArgs: {
    uri: string;
    fileUri: string;
    options: DownloadOptions;
  } = {
    uri: 'https://httpbin.org/get',
    fileUri: FileSystem.documentDirectory + 'downloadResponse.json',
    options: {
      md5: true,
      cache: false,
      headers: {
        Accept: 'application/json',
      },
    },
  };
  const uploadAsyncArgs: {
    url: string;
    fileUri: string;
    options: FileSystemUploadOptions;
  } = {
    url: 'https://httpbin.org/patch',
    fileUri: FileSystem.documentDirectory + 'downloadResponse.json',
    options: {
      fieldName: 'data',
      httpMethod: 'PATCH',
      uploadType: FileSystem.FileSystemUploadType.BINARY_CONTENT,
      headers: {
        Accept: 'application/json',
      },
    },
  };
  const [downloadResponse, setDownloadResponse] =
    useState<FileSystem.FileSystemDownloadResult>();
  const [uploadResponse, setUploadResponse] =
    useState<FileSystem.FileSystemUploadResult>();
  const handleDownloadAsync = async () => {
    const {uri, fileUri, options} = downloadAsyncArgs;
    FileSystem.downloadAsync(uri, fileUri, options)
      .then(setDownloadResponse)
      .catch((error) => setDownloadResponse(error.message));
  };
  const handleUploadAsync = async () => {
    const {url, fileUri, options} = uploadAsyncArgs;
    FileSystem.uploadAsync(url, fileUri, options)
      .then(setUploadResponse)
      .catch((error) => setUploadResponse(error.message));
  };
  return (
    <ScrollView style={styles.container}>
      <Button title="Download file" onPress={handleDownloadAsync} />
      <View style={styles.cell}>
        <Text style={styles.cellText}>
          {JSON.stringify(downloadResponse, null, 2)}
        </Text>
      </View>
      <Button title="Upload file" onPress={handleUploadAsync} />
      <View style={styles.cell}>
        <Text style={styles.cellText}>
          {JSON.stringify(uploadResponse, null, 2)}
        </Text>
      </View>
    </ScrollView>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    backgroundColor: 'white',
  },
  cell: {
    flex: 1,
    padding: 10,
    borderWidth: 2,
    justifyContent: 'center',
    borderColor: 'white',
  },
  cellText: {
    fontSize: 24,
    color: 'black',
  },
});
API reference
Check out the documentation page for info about this library, API reference and more Official Expo documentation for expo-file-system.
Constants
| Constant | Description | 
|---|---|
| documentDirectory | URI pointing to the directory where user documents for this app will be stored. E.g. /data/ | 
| cacheDirectory | URI pointing to the directory where temporary files used by this app will be stored. E.g. /cache/ | 
| bundleDirectory | URI to the directory where assets bundled with the application are stored. E.g. /pkg/bundle/index.hermes.bundle | 
Methods
| Method | Description | 
|---|---|
| copyAsync | Create a copy of a file or directory | 
| deleteAsync | Delete a file or directory | 
| downloadAsync | Download the contents at a remote URI to a file in the app's file system | 
| getContentUriAsync | Takes a file://URI and converts it into content URI (content://) so that it can be accessed by other applications outside of Expo | 
| getFreeDiskStorageAsync | Gets the available internal disk storage size, in bytes | 
| getInfoAsync | Get metadata information about a file, directory or external content/asset | 
| getTotalDiskCapacityAsync | Gets total internal disk storage size, in bytes | 
| makeDirectoryAsync | Create a new empty directory | 
| moveAsync | Move a file or directory to a new location | 
| readAsStringAsync | Read the entire contents of a file as a string | 
| readDirectoryAsync | Enumerate the contents of a directory | 
| uploadAsync | Upload the contents of the file pointed by fileUrito the remote url | 
| writeAsStringAsync | Write the entire contents of a file as a string | 
Supported URI schemes
In this table, you can see what type of URI can be handled by each method.
| Method name | Supported URI | 
|---|---|
| getInfoAsync | no scheme, for example /data/file.txt | 
| readAsStringAsync | no scheme | 
| writeAsStringAsync | no scheme | 
| deleteAsync | no scheme | 
| moveAsync | Source: no scheme; Destination: no scheme | 
| copyAsync | Source: no scheme; Destination: no scheme | 
| makeDirectoryAsync | no scheme | 
| readDirectoryAsync | no scheme | 
| downloadAsync | Source: http://,https://; Destination: no scheme | 
| uploadAsync | Source: no scheme; Destination: http://,https:// | 
| createDownloadResumable | Source: http://,https://; Destination: no scheme | 
Implementation details
On Vega getTotalDiskCapacityAsync always returns 0.
Additionally, the following classes are not supported on Vega:
- DownloadResumable
- FileSystemCancellableNetworkTask
- UploadTask
Supported versions
| Package Version | Based On | @amazon-devices/react-native-kepler version | 
|---|---|---|
| 2.0.x | 15.8.0 | 2.0.x | 
Additional resources
For information on additional libraries, see Supported Third-Party Libraries and Services.
Last updated: Sep 30, 2025

