docs/pages/versions/v55.0.0/sdk/filesystem.mdx
import APISection from '/components/plugins/APISection';
import { APIInstallSection } from '/components/plugins/InstallSection';
import { Collapsible } from '/ui/components/Collapsible';
import {
ConfigReactNative,
ConfigPluginExample,
ConfigPluginProperties,
} from '/ui/components/ConfigSection';
import { CODE } from '~/ui/components/Text';
expo-file-system provides access to files and directories stored on a device or bundled as assets into the native project. It also allows downloading files from the network.
You can configure expo-file-system using its built-in config plugin if you use config plugins in your project (Continuous Native Generation (CNG)). The plugin allows you to configure various properties that cannot be set at runtime and require building a new app binary to take effect. If your app does not use CNG, then you'll need to manually configure the library.
{
"expo": {
"plugins": [
[
"expo-file-system",
{
"supportsOpeningDocumentsInPlace": true,
"enableFileSharing": true
}
]
]
}
}
<ConfigPluginProperties
properties={[
{
name: 'supportsOpeningDocumentsInPlace',
platform: 'ios',
description:
'A boolean to enable LSSupportsOpeningDocumentsInPlace in Info.plist. This allows the app to open documents in place.',
default: 'false',
},
{
name: 'enableFileSharing',
platform: 'ios',
description:
"A boolean to enable UIFileSharingEnabled in Info.plist. This enables file sharing in the iOS Files app, making the app's Documents directory accessible to users through the Files app, iTunes File Sharing, and other file management tools.",
default: 'false',
},
]}
/>
If you're not using Continuous Native Generation (CNG) or you're using native ios project manually, then you need to add the LSSupportsOpeningDocumentsInPlace and UIFileSharingEnabled keys to your project's ios/[app]/Info.plist:
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>UIFileSharingEnabled</key>
<true/>
import { File, Directory, Paths } from 'expo-file-system';
The File and Directory instances hold a reference to a file, content, or asset URI.
The file or directory does not need to exist — an error will be thrown from the constructor only if the wrong class is used to represent an existing path (so if you try to create a File instance passing a path to an already existing directory).
type, size, creationDate, and moreFileHandle classdownloadFileAsync or expo/fetchimport { File, Paths } from 'expo-file-system';
try {
const file = new File(Paths.cache, 'example.txt');
file.create(); // can throw an error if the file already exists or no permission to create it
file.write('Hello, world!');
console.log(file.textSync()); // Hello, world!
} catch (error) {
console.error(error);
}
Usage with expo-document-picker:
import { File } from 'expo-file-system';
import * as DocumentPicker from 'expo-document-picker';
try {
const result = await DocumentPicker.getDocumentAsync({ copyToCacheDirectory: true });
if (!result.canceled) {
const { uri } = result.assets[0];
const file = new File(uri);
console.log(file.textSync());
}
} catch (error) {
console.error(error);
}
Using the built-in pickFileAsync or pickDirectoryAsync method on Android:
import { File } from 'expo-file-system';
try {
const file = new File.pickFileAsync();
console.log(file.textSync());
} catch (error) {
console.error(error);
}
Using downloadFileAsync:
import { Directory, File, Paths } from 'expo-file-system';
const url = 'https://pdfobject.com/pdf/sample.pdf';
const destination = new Directory(Paths.cache, 'pdfs');
try {
destination.create();
const output = await File.downloadFileAsync(url, destination);
console.log(output.exists); // true
console.log(output.uri); // path to the downloaded file, e.g., '${cacheDirectory}/pdfs/sample.pdf'
} catch (error) {
console.error(error);
}
Or using expo/fetch:
import { fetch } from 'expo/fetch';
import { File, Paths } from 'expo-file-system';
const url = 'https://pdfobject.com/pdf/sample.pdf';
const response = await fetch(url);
const src = new File(Paths.cache, 'file.pdf');
src.write(await response.bytes());
<Collapsible summary={<>Uploading files using <CODE>expo/fetch</CODE></>}>
You can upload files as blobs directly with fetch built into the Expo package:
import { fetch } from 'expo/fetch';
import { File, Paths } from 'expo-file-system';
const file = new File(Paths.cache, 'file.txt');
file.write('Hello, world!');
const response = await fetch('https://example.com', {
method: 'POST',
body: file,
});
Or using the FormData constructor:
import { fetch } from 'expo/fetch';
import { File, Paths } from 'expo-file-system';
const file = new File(Paths.cache, 'file.txt');
file.write('Hello, world!');
const formData = new FormData();
formData.append('data', file);
const response = await fetch('https://example.com', {
method: 'POST',
body: formData,
});
import { Directory, File, Paths } from 'expo-file-system';
try {
const file = new File(Paths.document, 'example.txt');
file.create();
console.log(file.uri); // '${documentDirectory}/example.txt'
const copiedFile = new File(Paths.cache, 'example-copy.txt');
file.copy(copiedFile);
console.log(copiedFile.uri); // '${cacheDirectory}/example-copy.txt'
file.move(Paths.cache);
console.log(file.uri); // '${cacheDirectory}/example.txt'
file.move(new Directory(Paths.cache, 'newFolder'));
console.log(file.uri); // '${cacheDirectory}/newFolder/example.txt'
} catch (error) {
console.error(error);
}
import * as FileSystem from 'expo-file-system/legacy';
import { File, Paths } from 'expo-file-system';
try {
const file = new File(Paths.cache, 'example.txt');
const content = await FileSystem.readAsStringAsync(file.uri);
console.log(content);
} catch (error) {
console.error(error);
}
import { Directory, Paths } from 'expo-file-system';
function printDirectory(directory: Directory, indent: number = 0) {
console.log(`${' '.repeat(indent)} + ${directory.name}`);
const contents = directory.list();
for (const item of contents) {
if (item instanceof Directory) {
printDirectory(item, indent + 2);
} else {
console.log(`${' '.repeat(indent + 2)} - ${item.name} (${item.size} bytes)`);
}
}
}
try {
printDirectory(new Directory(Paths.cache));
} catch (error) {
console.error(error);
}