Access to system directories (cache, document, bundle) and comprehensive path manipulation utilities with cross-platform compatibility and Apple shared container support.
Provides access to system directories and path manipulation utilities, extending PathUtilities with system-specific functionality.
/**
* Provides access to system directories and path utilities
*/
class Paths extends PathUtilities {
/** Cache directory - files can be deleted by system when storage is low */
static get cache(): Directory;
/** Bundle directory - contains app assets and resources */
static get bundle(): Directory;
/** Document directory - persistent storage safe from system deletion */
static get document(): Directory;
/** Apple shared containers for app groups (iOS only) */
static get appleSharedContainers(): Record<string, Directory>;
/** Total disk space on device in bytes */
static get totalDiskSpace(): number;
/** Available disk space on device in bytes */
static get availableDiskSpace(): number;
/** Returns path information for specified path segments */
static info(...uris: string[]): PathInfo;
}Access platform-specific directories with appropriate permissions and usage patterns.
/**
* Cache directory - temporary storage that can be cleared by system
* Use for downloaded files, generated thumbnails, and temporary data
*/
static get cache(): Directory;
/**
* Document directory - persistent user data storage
* Use for user-created files, app data, and important documents
*/
static get document(): Directory;
/**
* Bundle directory - read-only app resources and assets
* Contains files bundled with the application during build
*/
static get bundle(): Directory;
/**
* Apple shared containers for app group access (iOS only)
* Provides access to shared storage between apps in the same app group
*/
static get appleSharedContainers(): Record<string, Directory>;Usage Examples:
import { Paths } from "expo-file-system";
// Cache directory usage - temporary files
const tempFile = Paths.cache.createFile("temp-download.zip", "application/zip");
tempFile.write(downloadedData);
console.log(`Cached file at: ${tempFile.uri}`);
// Document directory usage - persistent storage
const userDocument = Paths.document.createFile("user-data.json", "application/json");
userDocument.write(JSON.stringify(userData));
// Bundle directory usage - read app assets
const configFile = new File(Paths.bundle, "config.json");
if (configFile.exists) {
const config = JSON.parse(await configFile.text());
console.log("App configuration:", config);
}
// Apple shared containers (iOS only)
const sharedContainers = Paths.appleSharedContainers;
Object.keys(sharedContainers).forEach(appGroupId => {
const containerDir = sharedContainers[appGroupId];
console.log(`App group ${appGroupId}: ${containerDir.uri}`);
});Monitor device storage space for intelligent caching and storage management.
/**
* Total disk space on the device's internal storage in bytes
*/
static get totalDiskSpace(): number;
/**
* Available disk space on the device's internal storage in bytes
*/
static get availableDiskSpace(): number;Usage Examples:
import { Paths } from "expo-file-system";
// Check available storage
const totalSpace = Paths.totalDiskSpace;
const availableSpace = Paths.availableDiskSpace;
const usedSpace = totalSpace - availableSpace;
console.log(`Total storage: ${(totalSpace / 1024 / 1024 / 1024).toFixed(2)} GB`);
console.log(`Available: ${(availableSpace / 1024 / 1024 / 1024).toFixed(2)} GB`);
console.log(`Used: ${(usedSpace / 1024 / 1024 / 1024).toFixed(2)} GB`);
// Storage management logic
const MINIMUM_FREE_SPACE = 100 * 1024 * 1024; // 100 MB
if (availableSpace < MINIMUM_FREE_SPACE) {
console.warn("Low storage space - cleaning cache...");
// Clear cache directory
const cacheContents = Paths.cache.list();
for (const item of cacheContents) {
if (item instanceof File) {
item.delete();
}
}
}
// Progressive quality based on storage
const storageRatio = availableSpace / totalSpace;
const imageQuality = storageRatio > 0.5 ? 'high' : storageRatio > 0.2 ? 'medium' : 'low';
console.log(`Using ${imageQuality} quality images based on available storage`);Query path existence and type information for any filesystem path.
/**
* Returns information about specified path(s)
* @param uris Path segments to join and query
* @returns PathInfo with existence and type information
*/
static info(...uris: string[]): PathInfo;
interface PathInfo {
/** Whether the path exists and is accessible */
exists: boolean;
/** Whether the path is a directory, null if path doesn't exist */
isDirectory: boolean | null;
}Usage Examples:
import { Paths } from "expo-file-system";
// Check if path exists and get type
const pathInfo = Paths.info("/data/user/documents/myfile.txt");
console.log(`Path exists: ${pathInfo.exists}`);
if (pathInfo.exists) {
console.log(`Is directory: ${pathInfo.isDirectory}`);
}
// Check multiple path segments
const nestedInfo = Paths.info("documents", "projects", "app");
if (nestedInfo.exists && nestedInfo.isDirectory) {
console.log("Project directory exists");
}
// Validate paths before operations
function safePathOperation(pathSegments: string[]) {
const info = Paths.info(...pathSegments);
if (!info.exists) {
throw new Error("Path does not exist");
}
if (info.isDirectory === null) {
throw new Error("Cannot determine path type");
}
return info.isDirectory ? "directory" : "file";
}Comprehensive path manipulation utilities inherited by the Paths class.
/**
* Joins path segments into a single path with proper URL encoding
* @param paths Array of path segments, File instances, or Directory instances
* @returns Joined path string
*/
static join(...paths: (string | File | Directory)[]): string;
/**
* Calculates relative path between two paths
* @param from Base path
* @param to Target path
* @returns Relative path string
*/
static relative(from: string | File | Directory, to: string | File | Directory): string;
/**
* Checks if a path is absolute
* @param path Path to check
* @returns True if path is absolute
*/
static isAbsolute(path: string | File | Directory): boolean;
/**
* Normalizes a path by resolving . and .. segments
* @param path Path to normalize
* @returns Normalized path string
*/
static normalize(path: string | File | Directory): string;
/**
* Returns the directory portion of a path
* @param path Path to process
* @returns Directory path string
*/
static dirname(path: string | File | Directory): string;
/**
* Returns the filename portion of a path
* @param path Path to process
* @param ext Optional extension to remove
* @returns Filename string
*/
static basename(path: string | File | Directory, ext?: string): string;
/**
* Returns the extension portion of a path
* @param path Path to process
* @returns Extension string including the dot
*/
static extname(path: string | File | Directory): string;
/**
* Parses a path into its component parts
* @param path Path to parse
* @returns Object with path components
*/
static parse(path: string | File | Directory): {
root: string;
dir: string;
base: string;
ext: string;
name: string;
};Usage Examples:
import { Paths, File, Directory } from "expo-file-system";
// Path joining with mixed types
const docDir = Paths.document;
const projectFile = new File(docDir, "projects", "app.json");
const configPath = Paths.join(docDir, "config", "settings.json");
console.log(`Config path: ${configPath}`);
// Relative path calculation
const relativePath = Paths.relative(
Paths.document.uri,
Paths.join(Paths.document, "subfolder", "file.txt")
);
console.log(`Relative path: ${relativePath}`);
// Path validation and normalization
const messyPath = "/documents/../documents/./files//data.txt";
const cleanPath = Paths.normalize(messyPath);
console.log(`Normalized: ${cleanPath}`);
// Path component extraction
const filePath = "/documents/projects/mobile-app/src/index.ts";
const parsed = Paths.parse(filePath);
console.log(`Directory: ${parsed.dir}`);
console.log(`Filename: ${parsed.name}`);
console.log(`Extension: ${parsed.ext}`);
// Cross-platform absolute path checking
const paths = [
"/absolute/unix/path",
"relative/path",
"file:///absolute/file/uri",
"C:\\Windows\\Path"
];
paths.forEach(path => {
console.log(`${path} is absolute: ${Paths.isAbsolute(path)}`);
});
// Safe filename extraction
function getFileInfo(path: string) {
const basename = Paths.basename(path);
const extension = Paths.extname(path);
const nameWithoutExt = Paths.basename(path, extension);
return {
fullname: basename,
name: nameWithoutExt,
extension: extension,
directory: Paths.dirname(path)
};
}
const fileInfo = getFileInfo("/documents/photos/vacation-2024.png");
console.log(fileInfo);
// Output: {
// fullname: "vacation-2024.png",
// name: "vacation-2024",
// extension: ".png",
// directory: "/documents/photos"
// }Handle platform differences and specialized directory access patterns.
Usage Examples:
import { Paths, Directory } from "expo-file-system";
import { Platform } from "react-native";
// Platform-specific directory setup
function setupAppDirectories() {
const appDataDir = Paths.document.createDirectory("AppData");
const cacheDir = Paths.cache.createDirectory("AppCache");
// iOS-specific shared container access
if (Platform.OS === 'ios') {
const sharedContainers = Paths.appleSharedContainers;
// Access shared container for app group
const appGroupId = "group.com.company.myapp";
if (sharedContainers[appGroupId]) {
const sharedDir = sharedContainers[appGroupId];
const sharedData = sharedDir.createFile("shared-config.json", "application/json");
console.log(`Shared data location: ${sharedData.uri}`);
}
}
return { appDataDir, cacheDir };
}
// Intelligent storage location selection
function selectStorageLocation(fileType: string, fileSize: number): Directory {
const availableSpace = Paths.availableDiskSpace;
const isLargeFile = fileSize > 10 * 1024 * 1024; // 10MB
const hasLowStorage = availableSpace < 100 * 1024 * 1024; // 100MB
// Use cache for large files when storage is limited
if (isLargeFile && hasLowStorage) {
console.log("Using cache directory due to storage constraints");
return Paths.cache;
}
// Use documents for important file types
const importantTypes = ['.json', '.xml', '.config', '.db'];
if (importantTypes.some(type => fileType.includes(type))) {
return Paths.document;
}
// Default to cache for temporary files
return Paths.cache;
}
// Storage monitoring and cleanup
function monitorStorage() {
const totalSpace = Paths.totalDiskSpace;
const availableSpace = Paths.availableDiskSpace;
const usagePercent = ((totalSpace - availableSpace) / totalSpace) * 100;
console.log(`Storage usage: ${usagePercent.toFixed(1)}%`);
// Cleanup strategy based on usage
if (usagePercent > 90) {
console.log("Critical storage - aggressive cleanup");
cleanupOldCacheFiles(7); // Clean files older than 7 days
} else if (usagePercent > 80) {
console.log("High storage usage - moderate cleanup");
cleanupOldCacheFiles(30); // Clean files older than 30 days
}
}
function cleanupOldCacheFiles(daysOld: number) {
const cutoffTime = Date.now() - (daysOld * 24 * 60 * 60 * 1000);
const cacheContents = Paths.cache.list();
cacheContents.forEach(item => {
if (item instanceof File && item.modificationTime) {
if (item.modificationTime < cutoffTime) {
console.log(`Cleaning up old cache file: ${item.name}`);
item.delete();
}
}
});
}