Filesystem access for React Native. Supports saving network requests directly to the filesystem. Supports Android scoped storage, a requirement when targeting API 30 or higher.
npm install react-native-file-access
cd ios && pod install
Apple restricts usage of certain privacy sensitive API calls. If you do not use disk space measurements or file timestamps, define the following variable in your Podfile to exclude restricted API calls. More details.
$RNFANoPrivacyAPI = true
If the app does not use autolinking, continue to the manual install instructions in the wiki.
| React Native | react-native-file-access |
|---|---|
| <= 0.64 | 1.x.x |
| 0.65+, old arch | 2.x.x, 3.x.x |
| 0.71+, new arch | 3.x.x |
| 0.77+, new arch | 4.x.x |
import { Dirs, FileSystem } from 'react-native-file-access';
// ...
const text = await FileSystem.readFile(Dirs.CacheDir + '/test.txt');
Dirs.CacheDirDirs.DatabaseDir (Android only)Dirs.DocumentDirDirs.LibraryDir (iOS & MacOS only)Dirs.MainBundleDirDirs.SDCardDir (Android only)FileSystem.cpExternal() when possible.FileSystem.appendFile(path: string, data: string, encoding?: 'utf8' | 'base64'): Promise<void>
data is assumed utf8.FileSystem.concatFiles(source: string, target: string): Promise<number>
FileSystem.cp(source: string, target: string, onProgress?: (bytesCopied: number, contentLength: number, done: boolean) => void): Promise<void>
FileSystem.cpAsset(asset: string, target: string, type?: 'asset' | 'resource'): Promise<void>
type is asset. Prefer this when possible.resource uses the Android res/ folder, and inherits the associated
naming restrictions.FileSystem.cpExternal(source: string, targetName: string, dir: 'audio' | 'downloads' | 'images' | 'video'): Promise<void>
Dirs.DocumentDir with UIFileSharingEnabled
and LSSupportsOpeningDocumentsInPlace enabled.FileSystem.df(): Promise<{ internal_free: number, internal_total: number, external_free?: number, external_total?: number }>
FileSystem.exists(path: string): Promise<boolean>
FileSystem.fetch(
resource: string,
init: { body?: string, headers?: { [key: string]: string }, method?: string, network?: 'any' | 'unmetered', path?: string },
onProgress?: (bytesRead: number, contentLength: number, done: boolean) => void
): Promise<FetchResult>
type FetchResult = {
getHeader: (header: string) => string | undefined;
headers: { [key: string]: string };
ok: boolean;
redirected: boolean;
status: number;
statusText: string;
url: string;
}
resource - URL to fetch.init.path - Optional filesystem location to save the response.init.network - Optional restriction on network type. Specifying
unmetered will reject the request if unmetered connections (most likely
WiFi) are unavailable.onProgress - Optional callback to listen to download progress. Events
are rate limited, so do not rely on done becoming true.
contentLength is only accurate if the server sends the correct headers.FileSystem.fetchManaged(
resource: string,
init: { body?: string, headers?: { [key: string]: string }, method?: string, network?: 'any' | 'unmetered', path?: string },
onProgress?: (bytesRead: number, contentLength: number, done: boolean) => void
): ManagedFetchResult
type ManagedFetchResult = {
cancel: () => Promise<void>;
result: Promise<FetchResult>;
}
fetch(), with the option to cancel before completion.FileSystem.getAppGroupDir(groupName: string): Promise<string>
FileSystem.hardlink(source: string, target: string): Promise<void>
FileSystem.hash(path: string, algorithm: 'MD5' | 'SHA-1' | 'SHA-224' | 'SHA-256' | 'SHA-384' | 'SHA-512'): Promise<string>
FileSystem.isDir(path: string): Promise<boolean>
FileSystem.ls(path: string): Promise<string[]>
FileSystem.mkdir(path: string): Promise<string>
FileSystem.mv(source: string, target: string): Promise<void>
FileSystem.readFile(path: string, encoding?: 'utf8' | 'base64'): Promise<string>
FileSystem.readFileChunk(path: string, offset: number, length: number, encoding?: 'utf8' | 'base64'): Promise<string>
offset, reading for length bytes.FileSystem.stat(path: string): Promise<FileStat>
type FileStat = {
filename: string;
lastModified: number;
path: string;
size: number;
type: 'directory' | 'file';
}
FileSystem.statDir(path: string): Promise<FileStat[]>
FileSystem.symlink(source: string, target: string): Promise<void>
FileSystem.unlink(path: string): Promise<void>
FileSystem.unzip(source: string, target: string): Promise<void>
FileSystem.writeFile(path: string, data: string, encoding?: 'utf8' | 'base64'): Promise<void>
data is assumed utf8.Util.basename(path: string, separator?: string): string
separator is /.Util.dirname(path: string, separator?: string): string
separator is /.Util.extname(path: string, separator?: string): string
separator is /.For simple usage, use FileSystem.cpExternal() to submit files to general
scoped storage categories.
Most functions in this library work with content:// Android resource uris.
To gain access to a resource uri, currently use a library such as
react-native-document-picker or
react-native-scoped-storage.
Eventually this library will incorporate file/folder selector functionality
(pull requests welcome).
Note:
- When generating a scoped storage resource uri, use the helper
AndroidScoped.appendPath(dir, 'data.txt'), not dir + '/data.txt'.
- Android may change the name of created files/folders.
AndroidScoped.appendPath(basePath: string, segment: string): string
For ease of testing, this library contains a mock implementation: jest/react-native-file-access.ts.
Install the mock by adding the following to the jest setup file.
import { mockRnfaModule } from 'react-native-file-access/jest/mock';
jest.mock('react-native-file-access', () => mockRnfaModule);
This may require editing the configured
transformIgnorePatterns.
// (Optional) clear mock state between tests:
import { FileSystem } from 'react-native-file-access/jest/mock';
beforeEach(() => {
FileSystem.filesystem.clear();
});
Alternatively, if modifications are required, copy the mock into the
__mocks__
folder, and edit as needed.
This library aims to be a modern implementation of filesystem api, using Kotlin/Swift and latest best practices. For a more established library, consider:
For more greater control over network requests, consider react-native-blob-courier.
See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT
$ claude mcp add react-native-file-access \
-- python -m otcore.mcp_server <graph>