
The ability to interact with a device’s file system becomes crucial the moment your React Native app needs to handle real user data. I’ve run into this while building apps that needed to store data locally, manage downloads, and work with images reliably across devices. This is where React Native FS comes into play, providing a powerful solution for developers working with React Native.
React Native FS, often referred to as RNFS, is a comprehensive library that bridges the gap between React Native and the native file systems of iOS and Android. I’ve used it in real-world apps where direct file access was unavoidable, and it consistently simplifies complex filesystem tasks. It offers a unified API that allows developers to perform a wide range of file operations, from simple read and write tasks to more complex operations like file downloads, uploads, and directory management.
With React Native FS, you can seamlessly integrate file system capabilities into your app, enhancing its functionality and user experience.
Accessing the filesystem is not just a technical requirement. I’ve seen it become a hard blocker when apps fail to support features users expect by default, especially in production builds.
Here are some common scenarios where React Native FS becomes essential:
Editing existing images or files: Apps like image editors, document scanners, or note-taking tools need access to files already stored on the device. React Native FS allows you to read these files, modify them, and save changes locally.
Downloading and managing files: Whether it’s PDFs, invoices, or media files, many mobile apps need to download content and store it on the device. React Native FS lets you download files, track progress, and manage storage locations safely.
Offline-first applications: Apps that work without an internet connection often store user data locally. React Native FS makes it possible to read and write files offline, then sync them later when connectivity is restored.
Sharing files between apps: When users want to share documents, images, or reports with other apps, filesystem access is required to read file content and pass it to sharing modules.
Storage cleanup and performance control: Over time, apps accumulate cached or temporary files. React Native FS allows you to check file existence, remove unused files, and keep storage usage under control.
By enabling these workflows, React Native FS helps bridge the gap between user expectations and what a mobile app can do behind the scenes.

To begin using React Native FS in your project, this is the setup I’ve personally followed across multiple React Native apps. You can do this using npm or yarn:
npm install react-native-fs
# or
yarn add react-native-fsAfter installation, you'll need to link the library. For React Native versions 0.60 and above, this process is typically automatic. For earlier versions, you might need to run:
react-native link react-native-fsNow, let's dive into some practical examples of how to use React Native FS.
When working with React Native FS, understanding where files are stored is just as important as knowing how to read or write them. File locations behave differently on iOS and Android, and I’ve learned the hard way that choosing the wrong path can lead to disappearing files, permission errors, or unexpected data loss.
React Native FS solves this by providing predefined directory paths that work consistently across platforms. These paths help you store files safely, manage permissions correctly, and avoid platform-specific issues.
Below are the most commonly used file paths in React Native FS and when to use each one.

This is the most important and commonly used directory in React Native FS.
Use this directory for:
Example:
RNFS.DocumentDirectoryPath
This is the safest default for most file operations.
This directory is designed for short-lived files.
Use this directory for:
Example:
RNFS.TemporaryDirectoryPath
Avoid storing important or user-facing data here.
This path points to the public Downloads folder on Android devices.
Use this directory only when:
Example:
RNFS.DownloadDirectoryPath
This represents shared external storage on Android.
We build powerful React Native apps that run smoothly on iOS and Android — fast, reliable, and ready to scale.
Use with caution and only when absolutely necessary.
Example:
RNFS.ExternalStorageDirectoryPath
This directory contains bundled app resources.
Example:
RNFS.MainBundleDirectory
Do not attempt to save or modify files here.
For most apps:
Choosing the right path prevents permission issues, accidental data loss, and unexpected behavior across iOS and Android devices.
One of the most common operations is reading files. Below is a simple React Native FS example that shows how to read file contents from the app’s document directory.
import RNFS from 'react-native-fs';
const readFile = async () => {
try {
const contents = await RNFS.readFile(RNFS.DocumentDirectoryPath + '/myfile.txt', 'utf8');
console.log(contents);
} catch (error) {
console.error('Error reading file:', error);
}
};This example reflects how I typically read files from the app’s document directory when validating filesystem behavior during development.
Writing files is equally straightforward:
import RNFS from 'react-native-fs';
const writeFile = async () => {
const path = RNFS.DocumentDirectoryPath + '/myfile.txt';
const contents = 'Hello, React Native FS!';
try {
await RNFS.writeFile(path, contents, 'utf8');
console.log('File written successfully!');
} catch (error) {
console.error('Error writing file:', error);
}
};This code snippet writes a simple string to a file in the document directory.
React Native FS also provides functionality for downloading files:
import RNFS from 'react-native-fs';
const downloadFile = () => {
const fromUrl = 'https://example.com/myfile.pdf';
const toFile = `${RNFS.DocumentDirectoryPath}/myfile.pdf`;
const options = {
fromUrl: fromUrl,
toFile: toFile,
begin: (res) => {
console.log('Download started');
},
progress: (res) => {
let progressPercent = (res.bytesWritten / res.contentLength) * 100;
console.log(`Downloaded ${progressPercent.toFixed(2)}%`);
},
};
RNFS.downloadFile(options).promise
.then((res) => {
console.log('File downloaded successfully');
})
.catch((error) => {
console.error('Error downloading file:', error);
});
};This example shows how to download a file, complete with progress tracking.
In some cases, you may want users to open downloaded files outside your app. For example, opening a PDF, image, or document in another installed app. In such scenarios, React Native FS is often used together with react-native-file-viewer to open downloaded files in external applications.
Working with the filesystem in React Native is not the same on Android and iOS, and most real issues I’ve encountered came from assuming both platforms behave the same. Each platform handles permissions differently, and understanding this early prevents unexpected errors.
On iOS, React Native FS works inside your app’s sandbox by default. This means:
For most use cases like saving data, images, or downloads inside the app, no additional setup is required.
Android is more restrictive and depends on the OS version.
For Android 10 and above (Scoped Storage):
For Android 9 and below:
If your app needs access to external storage, request permission explicitly:
import { PermissionsAndroid, Platform } from 'react-native';
const requestStoragePermission = async () => {
if (Platform.OS === 'android') {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
{
title: 'Storage Permission',
message: 'App needs access to storage to save files',
buttonPositive: 'OK',
}
);
return granted === PermissionsAndroid.RESULTS.GRANTED;
} catch (error) {
console.warn(error);
return false;
}
}
return true;
};Always request permissions before downloading or writing files to external directories.
Handling permissions correctly ensures your app works reliably across devices and avoids crashes or silent failures.
React Native FS also allows you to manage directories:
import RNFS from 'react-native-fs';
const createDirectory = async () => {
const path = RNFS.DocumentDirectoryPath + '/MyNewFolder';
try {
await RNFS.mkdir(path);
console.log('Directory created successfully');
} catch (error) {
console.error('Error creating directory:', error);
}
};This code creates a new directory in the app's document directory.
Many apps need to display files stored on the device, such as documents, images, or downloaded content. React Native FS provides the readDir method to list files and folders inside a directory.
Here’s a simple example that reads all files from the app’s document directory:
import RNFS from 'react-native-fs';
const listFiles = async () => {
try {
const files = await RNFS.readDir(RNFS.DocumentDirectoryPath);
files.forEach(item => {
console.log(
item.name,
item.isFile() ? 'File' : 'Folder'
);
});
} catch (error) {
console.error('Error reading directory:', error);
}
};Each item returned by readDir contains useful metadata such as:
You can also check whether an item is a file or a directory using:
By listing directories properly, you can build file browsers, document pickers, and storage management features directly inside your React Native app.
Before performing operations on files, it's often useful to check if they exist:
import RNFS from 'react-native-fs';
const checkFileExists = async () => {
const path = RNFS.DocumentDirectoryPath + '/myfile.txt';
try {
const exists = await RNFS.exists(path);
console.log(`File exists: ${exists}`);
} catch (error) {
console.error('Error checking file existence:', error);
}
};
This function checks whether a specific file exists in the document directory.
Apps often need to remove files, especially once you start thinking about long-term storage usage and performance, something I’ve had to address in production apps. React Native FS supports this with the unlink() method.
We build powerful React Native apps that run smoothly on iOS and Android — fast, reliable, and ready to scale.
Before deleting, it’s a good idea to confirm the file exists:
import RNFS from 'react-native-fs';
const deleteFile = async () => {
const path = `${RNFS.DocumentDirectoryPath}/myfile.txt`;
try {
const exists = await RNFS.exists(path);
if (!exists) {
console.log('File does not exist, nothing to delete.');
return;
}
await RNFS.unlink(path);
console.log('File deleted successfully!');
} catch (error) {
console.error('Error deleting file:', error);
}
};
Delete a folder (directory)
You can delete a folder the same way:
import RNFS from 'react-native-fs';
const deleteFolder = async () => {
const folderPath = `${RNFS.DocumentDirectoryPath}/MyNewFolder`;
try {
const exists = await RNFS.exists(folderPath);
if (!exists) {
console.log('Folder does not exist, nothing to delete.');
return;
}
await RNFS.unlink(folderPath);
console.log('Folder deleted successfully!');
} catch (error) {
console.error('Error deleting folder:', error);
}
};Adding a cleanup workflow helps keep your app faster, prevents storage bloat, and improves user experience over time.
1. Error Handling: Always wrap your file operations in try-catch blocks to handle potential errors gracefully.
2. Permissions: Be aware of the permissions required for file operations, especially on Android. You may need to request additional permissions for certain operations.
3. Performance: For large files or frequent operations, consider using streams or chunked operations to avoid memory issues.
4. Security: Be cautious about where you read from and write to. Stick to app-specific directories when possible.
5. Cleanup: Remember to clean up temporary files and manage your app's storage usage responsibly.
While React Native FS is powerful and useful in many scenarios, I’ve also learned that it’s not the right solution for every file-related requirement. Knowing when not to use it can help you avoid performance issues, maintenance problems, or architectural limitations later on.
Below are situations where React Native FS may not be the best choice.
React Native FS is designed for direct file access within the app lifecycle. It is not ideal for long-running background tasks such as continuous file syncing, scheduled uploads, or background media processing. In these cases, native background services or server-side processing are more reliable.
If your app primarily depends on syncing files across devices in real time, React Native FS alone is not sufficient. Cloud storage solutions or backend-managed file systems handle versioning, conflict resolution, and large-scale data consistency better than local filesystem access.
For apps that deal with very large video files, live media streaming, or complex media transformations, relying entirely on React Native FS can lead to memory pressure and performance bottlenecks. Native media libraries or platform-specific APIs are more suitable for these use cases.
On iOS, apps are sandboxed and cannot access files outside their own container. On Android, access to shared storage is increasingly restricted due to scoped storage. If your app requires unrestricted access to user files across the device, React Native FS will be limited by platform security rules.
React Native FS works well for local storage, offline-first apps, and moderate file operations. However, it is not designed for enterprise-grade file processing, high-concurrency workloads, or large-scale production pipelines where backend infrastructure is required.
If your application requires centralized access control, audit logs, or strict compliance policies, storing sensitive files locally using React Native FS may not be appropriate. Server-side storage with managed security controls is a safer approach in such cases.
Yes. React Native FS is widely used in production apps. Just make sure to handle permissions properly and avoid blocking the UI with large file operations.
This usually happens due to Android storage permissions or scoped storage restrictions. Always use app-specific directories like DocumentDirectoryPath and request permissions when accessing public folders.
Files are stored inside app-specific directories such as DocumentDirectoryPath. These locations are private to your app and persist between app launches.
No. On iOS, apps are sandboxed. On Android, access to public storage requires explicit permissions and is restricted on newer OS versions.
Avoid it for heavy background file processing or cloud sync logic. In such cases, native modules or backend-based storage solutions work better.
The most common issues are missing permissions, incorrect file paths, and attempting to access restricted directories.
React Native FS has been a reliable tool in my React Native apps work whenever filesystem access was unavoidable, from simple reads to more complex file management workflows, from basic read and write operations to more complex file management tasks. It provides a robust and flexible API for all your file system needs.
If you're looking to take your React Native app to the next level with advanced file system capabilities, consider reaching out to F22 Labs. Our team can help you implement efficient file management solutions, optimize your app's performance, and create a seamless user experience. Hire React Native Developers from F22 Labs and let us help you unlock the full potential of your mobile application with our deep expertise in React Native and file system management.