expo-file-system
Version: 55.0.6
Provides access to the local file system on the device. Read, write, delete files and directories, download files, and manage app storage with a modern, Promise-based API.
Installation
npx expo install expo-file-system
Usage
import * as FileSystem from 'expo-file-system';
// Modern API (Recommended)
import { Paths, File, Directory } from 'expo-file-system';
const file = new File(Paths.cache, 'notes.txt');
await file.create();
await file.write('Hello, World!');
const content = await file.text();
Modern API (v55+)
Paths
Access system directories:
Cache directory – files can be deleted by the systemconst cacheDir = Paths.cache;
const file = new File(cacheDir, 'temp.json');
Document directory – persistent storage safe from system deletionconst docDir = Paths.document;
const file = new File(docDir, 'data.db');
Bundle directory – contains assets bundled with the app (read-only)const bundleDir = Paths.bundle;
const asset = new File(bundleDir, 'config.json');
File Class
Represents a file on the filesystem:
import { File, Paths } from 'expo-file-system';
const file = new File(Paths.document, 'notes', 'note.txt');
Methods
Creates the file if it doesn’t exist
file.write(content)
(content: string | Uint8Array) => Promise<void>
Writes content to the fileawait file.write('Hello, World!');
await file.write(new Uint8Array([1, 2, 3]));
Reads file content as textconst content = await file.text();
file.bytes()
() => Promise<Uint8Array>
Reads file content as bytesconst bytes = await file.bytes();
Checks if the file exists
file.copy(destination)
(destination: File | Directory) => Promise<File>
Copies the file to a new locationconst newFile = await file.copy(Paths.cache);
file.move(destination)
(destination: File | Directory) => Promise<File>
Moves the file to a new location
Properties
The file URI (e.g., file:///path/to/file.txt)
File extension (e.g., .txt, .json)
The directory containing this file
Directory Class
Represents a directory on the filesystem:
import { Directory, Paths } from 'expo-file-system';
const dir = new Directory(Paths.document, 'myFolder');
Methods
Creates the directory if it doesn’t exist
Deletes the directory and its contents
Checks if the directory exists
dir.list()
() => (File | Directory)[]
Lists contents of the directoryconst contents = dir.list();
for (const item of contents) {
if (item instanceof File) {
console.log('File:', item.name);
} else {
console.log('Directory:', item.name);
}
}
dir.createFile(name, mimeType)
(name: string, mimeType?: string) => File
Creates a new file in this directoryconst file = dir.createFile('data.json', 'application/json');
dir.createDirectory(name)
(name: string) => Directory
Creates a new subdirectoryconst subdir = dir.createDirectory('subfolder');
Properties
Download Files
File.downloadFileAsync(url, destination, options)
Downloads a file from a URLconst file = await File.downloadFileAsync(
'https://example.com/file.pdf',
Paths.document,
{
headers: { 'Authorization': 'Bearer token' }
}
);
Examples
Read and Write Text Files
import { File, Paths } from 'expo-file-system';
// Write to a file
const file = new File(Paths.document, 'notes.txt');
await file.write('My notes content');
// Read from a file
const content = await file.text();
console.log(content); // "My notes content"
// Append to a file
const existingContent = await file.text();
await file.write(existingContent + '\nNew line');
Work with JSON
import { File, Paths } from 'expo-file-system';
interface UserData {
name: string;
email: string;
}
const dataFile = new File(Paths.document, 'user-data.json');
// Write JSON
const userData: UserData = {
name: 'John Doe',
email: 'john@example.com'
};
await dataFile.write(JSON.stringify(userData, null, 2));
// Read JSON
const json = await dataFile.text();
const loaded: UserData = JSON.parse(json);
console.log(loaded.name); // "John Doe"
Create Directory Structure
import { Directory, File, Paths } from 'expo-file-system';
// Create nested directories
const appData = new Directory(Paths.document, 'myapp');
await appData.create();
const imagesDir = new Directory(appData, 'images');
await imagesDir.create();
const cacheDir = new Directory(appData, 'cache');
await cacheDir.create();
// Create file in subdirectory
const configFile = new File(appData, 'config.json');
await configFile.write(JSON.stringify({ version: '1.0' }));
List Directory Contents
import { Directory, File, Paths } from 'expo-file-system';
const dir = new Directory(Paths.document);
const contents = dir.list();
for (const item of contents) {
if (item instanceof File) {
console.log(`File: ${item.name} (${item.size} bytes)`);
} else if (item instanceof Directory) {
console.log(`Directory: ${item.name}`);
}
}
Download and Save File
import { File, Paths } from 'expo-file-system';
async function downloadImage(url: string) {
const file = await File.downloadFileAsync(
url,
Paths.document,
{
headers: {
'User-Agent': 'MyApp/1.0'
}
}
);
console.log('Downloaded to:', file.uri);
return file;
}
await downloadImage('https://example.com/photo.jpg');
Copy and Move Files
import { File, Paths } from 'expo-file-system';
// Create a file
const original = new File(Paths.cache, 'temp.txt');
await original.write('Temporary data');
// Copy to documents (persistent storage)
const persistent = await original.copy(Paths.document);
// Move file to new location
const renamed = await persistent.move(
new File(Paths.document, 'permanent.txt')
);
// Delete original cache file
await original.delete();
Check File Existence
import { File, Paths } from 'expo-file-system';
const file = new File(Paths.document, 'settings.json');
if (await file.exists()) {
const data = await file.text();
console.log('Settings loaded:', data);
} else {
// Create default settings
await file.write(JSON.stringify({ theme: 'light' }));
}
Binary Data Handling
import { File, Paths } from 'expo-file-system';
// Write binary data
const binaryFile = new File(Paths.document, 'data.bin');
const bytes = new Uint8Array([72, 101, 108, 108, 111]); // "Hello"
await binaryFile.write(bytes);
// Read binary data
const readBytes = await binaryFile.bytes();
console.log(readBytes); // Uint8Array(5) [72, 101, 108, 108, 111]
// Convert to string
const text = new TextDecoder().decode(readBytes);
console.log(text); // "Hello"
Stream Large Files
import { File, Paths } from 'expo-file-system';
const file = new File(Paths.document, 'large-file.txt');
// Write stream
const writable = file.writableStream();
const writer = writable.getWriter();
for (let i = 0; i < 1000; i++) {
await writer.write(new TextEncoder().encode(`Line ${i}\n`));
}
await writer.close();
// Read stream
const readable = file.readableStream();
const reader = readable.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
console.log('Chunk:', new TextDecoder().decode(value));
}
Storage Info
import { Paths } from 'expo-file-system';
const totalSpace = Paths.totalDiskSpace;
const availableSpace = Paths.availableDiskSpace;
console.log(`Total: ${(totalSpace / 1024 / 1024 / 1024).toFixed(2)} GB`);
console.log(`Available: ${(availableSpace / 1024 / 1024 / 1024).toFixed(2)} GB`);
console.log(`Used: ${((totalSpace - availableSpace) / totalSpace * 100).toFixed(1)}%`);
Legacy API
For backwards compatibility, the legacy API is still available:
import * as FileSystem from 'expo-file-system/legacy';
// Write file
await FileSystem.writeAsStringAsync(
FileSystem.documentDirectory + 'file.txt',
'content'
);
// Read file
const content = await FileSystem.readAsStringAsync(
FileSystem.documentDirectory + 'file.txt'
);
Use the modern API (File, Directory, Paths) for new projects. The legacy API is maintained for compatibility only.
TypeScript
import { File, Directory, Paths } from 'expo-file-system';
const file: File = new File(Paths.document, 'data.txt');
const dir: Directory = new Directory(Paths.cache, 'temp');
const content: string = await file.text();
const bytes: Uint8Array = await file.bytes();
const exists: boolean = await file.exists();
| Platform | Supported |
|---|
| iOS | ✅ |
| Android | ✅ |
| Web | ✅ (Limited) |
On web, file system access is limited to browser storage. Not all features are available.
Best Practices
- Use Document Directory: Store user data in
Paths.document for persistence
- Use Cache Directory: Store temporary data in
Paths.cache
- Check Existence: Always check if files exist before reading
- Handle Errors: Wrap file operations in try/catch blocks
- Clean Up: Delete unnecessary files from cache regularly
Resources