@vali98/react-native-fs
v0.2.4
Published
Download folder access for react-native
Readme
react-native-local-download
Simple download folder access for react-native
Like my projects? Support me on ko-fi!
This package implements a few utility functions used in ChatterUI:
- Saving files to the android Downloads folder
- FileDescriptor access
- Persist access to SAF content
- Copying files directly from SAF
This package is intended to be used with other file-system packages such as expo-file-system or react-native-fs.
This was not tested on lower Android SDK APIs, might not work on Android 9 and below.
Installation
npm install @vali98/react-native-fsAPI Reference
localDownload(uri: string, never_ask_function?: () => void): Promise<void>
Saves a file to the system Downloads folder.
Parameters:
uri- Path to the file to download (file:// URI)never_ask_function- (Optional) Callback triggered if user permanently denies storage permission
Platform Support: Android & iOS
Example:
import { localDownload } from '@vali98/react-native-fs'
// Basic usage
await localDownload('/path/to/file.txt')
// With permission callback
await localDownload('/path/to/file.txt', () => {
console.log('User denied permissions permanently')
})copyFileSAF(sourceUri: string, destPath: string, onProgress?: (progress: CopyProgress) => void): Promise<void>
Copies a file from a Storage Access Framework (SAF) URI to a local file path. Provides real-time progress updates.
Parameters:
sourceUri- SAF content:// URI of the source filedestPath- Destination file:// path where the file will be copiedonProgress- (Optional) Callback function called with progress updates
Progress Object:
interface CopyProgress {
bytesCopied: number // Bytes copied so far
totalBytes: number // Total file size
percentComplete: number // 0-100 percentage
bytesPerSec: number // Transfer speed in bytes/second
}Platform Support: Android only
Errors:
- Throws
TypeErrorif sourceUri is not a content:// URI - Rejects with
COPY_ERRORif file copy fails - Rejects with
COPY_PERMISSION_DENIEDif access is denied
Example:
import { copyFileSAF, type CopyProgress } from '@vali98/react-native-fs'
await copyFileSAF(
contentUri,
'/path/to/app/private/file.txt',
(progress: CopyProgress) => {
const speedMB = (progress.bytesPerSec / (1024 * 1024)).toFixed(2)
console.log(`${progress.percentComplete.toFixed(1)}% - ${speedMB} MB/s`)
}
)getContentFd(uri: string): Promise<string>
Gets a file descriptor from a content:// URI. Useful for advanced file operations.
Parameters:
uri- SAF content:// URI
Returns: File descriptor as a string
Platform Support: Android only
Errors:
- Throws
TypeErrorif uri is not a content:// URI - Rejects with
FD_OPEN_FAILEDif file descriptor cannot be opened
Example:
import { getContentFd } from '@vali98/react-native-fs'
const fd = await getContentFd(contentUri)
// Use fd for native operations...closeFd(fd: string): Promise<void>
Closes a file descriptor obtained from getContentFd().
Parameters:
fd- File descriptor string or path
Platform Support: Android only
Example:
import { getContentFd, closeFd } from '@vali98/react-native-fs'
const fd = await getContentFd(contentUri)
// Use fd...
await closeFd(fd)persistContentPermission(uri: string): Promise<void>
Persists access permission to a SAF URI, allowing future access without the user needing to re-grant permissions.
Parameters:
uri- SAF content:// URI to persist
Platform Support: Android only
Errors:
- Rejects with
PERSIST_PERMISSION_DENIEDif the URI doesn't support persistent access
Example:
import { persistContentPermission } from '@vali98/react-native-fs'
// After user picks a file via SAF
await persistContentPermission(selectedContentUri)
// Later, can access the same URI without re-promptingrequestStoragePermission(): Promise<PermissionStatus>
Manually request storage permissions. Automatically handles Android API level differences (Android 13+ uses per-file permissions).
Returns: One of 'granted', 'denied', or 'never_ask_again'
Platform Support: Android only (returns 'granted' on iOS)
Example:
import { requestStoragePermission } from '@vali98/react-native-fs'
const result = await requestStoragePermission()
if (result === 'granted') {
// Proceed with file operations
}Types
CopyProgress
interface CopyProgress {
bytesCopied: number // Bytes copied so far
totalBytes: number // Total file size in bytes
percentComplete: number // 0-100 percentage complete
bytesPerSec: number // Transfer speed in bytes/second
}Contributing
See the contributing guide to learn how to contribute to the repository and the development workflow.
License
MIT
Made with create-react-native-library
