Provides comprehensive access to the local file system on mobile devices through Expo's module system.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Directory management including creation, listing contents, copying, moving, and deletion. Provides recursive operations and metadata access with cross-platform compatibility.
Represents a directory on the filesystem with comprehensive management capabilities.
/**
* Represents a directory on the filesystem.
* A Directory instance can be created for any path, and does not need to exist during creation.
*/
class Directory {
/**
* Creates an instance of a directory
* @param uris An array of string URIs, File instances, and Directory instances
*/
constructor(...uris: (string | File | Directory)[]);
/** Directory URI - read-only but may change after move operations */
readonly uri: string;
/** Directory name */
readonly name: string;
/** Parent directory */
readonly parentDirectory: Directory;
/** Whether the directory exists and can be accessed */
exists: boolean;
/** Directory size in bytes, null if directory doesn't exist */
size: number | null;
}Create directories with configurable options for intermediate directories and overwrite behavior.
/**
* Creates a directory at the specified path
* @param options Directory creation options
* @throws Error if containing folder doesn't exist or insufficient permissions
*/
create(options?: DirectoryCreateOptions): void;
interface DirectoryCreateOptions {
/** Whether to create intermediate directories if they don't exist */
intermediates?: boolean;
/** Whether to overwrite the directory if it exists */
overwrite?: boolean;
/** Whether the operation is idempotent (safe to call multiple times) */
idempotent?: boolean;
}Usage Examples:
import { Directory, Paths } from "expo-file-system";
// Create simple directory
const simpleDir = new Directory(Paths.document, "photos");
simpleDir.create();
// Create nested directory structure
const nestedDir = new Directory(Paths.document, "app", "cache", "images");
nestedDir.create({ intermediates: true });
// Idempotent creation (won't fail if already exists)
const configDir = new Directory(Paths.document, "config");
configDir.create({ idempotent: true });
// Force overwrite existing directory
const tempDir = new Directory(Paths.cache, "temp");
tempDir.create({ overwrite: true });Create and manage files and subdirectories within a directory.
/**
* Creates a new file in the directory
* @param name File name including extension
* @param mimeType MIME type for the file, or null for auto-detection
* @returns File instance for the created file
*/
createFile(name: string, mimeType: string | null): File;
/**
* Creates a new subdirectory
* @param name Directory name
* @returns Directory instance for the created subdirectory
*/
createDirectory(name: string): Directory;Usage Examples:
import { Directory, Paths } from "expo-file-system";
const projectDir = new Directory(Paths.document, "my-project");
projectDir.create();
// Create files in the directory
const configFile = projectDir.createFile("config.json", "application/json");
configFile.write('{"version": "1.0"}');
const logFile = projectDir.createFile("app.log", "text/plain");
logFile.write("Application started\n");
// Create subdirectories
const assetsDir = projectDir.createDirectory("assets");
const dataDir = projectDir.createDirectory("data");
assetsDir.create();
dataDir.create();
// Create files in subdirectories
const imageFile = assetsDir.createFile("logo.png", "image/png");
const dataFile = dataDir.createFile("users.json", "application/json");List and inspect directory contents with type information.
/**
* Lists the contents of a directory
* @returns Array of Directory and File instances
* @throws Error if directory doesn't exist or insufficient permissions
*/
list(): (Directory | File)[];
/**
* Internal method for listing directory contents as records
* @returns Array of objects with isDirectory flag and uri
* @hidden This method is internal and may be removed in future versions
*/
listAsRecords(): { isDirectory: string; uri: string }[];Usage Examples:
import { Directory, File, Paths } from "expo-file-system";
const documentsDir = new Directory(Paths.document);
// List all contents
const contents = documentsDir.list();
console.log(`Found ${contents.length} items:`);
contents.forEach(item => {
if (item instanceof File) {
console.log(`📄 File: ${item.name} (${item.size} bytes)`);
} else if (item instanceof Directory) {
console.log(`📁 Directory: ${item.name}`);
}
});
// Filter files by extension
const textFiles = contents.filter(item =>
item instanceof File && item.extension === '.txt'
);
// Count directories
const subdirectories = contents.filter(item => item instanceof Directory);
console.log(`Found ${subdirectories.length} subdirectories`);Copy, move, rename, and delete directories with all contents.
/**
* Copies a directory and all its contents to a new location
* @param destination Target directory or file path
*/
copy(destination: Directory | File): void;
/**
* Moves a directory to a new location, updating the uri property
* @param destination Target directory or file path
*/
move(destination: Directory | File): void;
/**
* Renames a directory in the same parent directory
* @param newName New directory name
*/
rename(newName: string): void;
/**
* Deletes a directory and all its contents recursively
* @throws Error if directory doesn't exist or cannot be deleted
*/
delete(): void;Usage Examples:
import { Directory, Paths } from "expo-file-system";
const sourceDir = new Directory(Paths.document, "source-project");
const backupLocation = new Directory(Paths.document, "backups");
// Create backup by copying
sourceDir.copy(backupLocation);
// Move to archive location
const archiveDir = new Directory(Paths.document, "archive");
archiveDir.create();
sourceDir.move(archiveDir);
// Rename directory
sourceDir.rename("archived-project");
// Clean up old directories
const tempDir = new Directory(Paths.cache, "temp-data");
if (tempDir.exists) {
tempDir.delete(); // Recursively deletes all contents
}Access directory information including size calculation and modification times.
/**
* Retrieves detailed directory metadata
* @returns Directory information object
* @throws Error if insufficient permissions or directory doesn't exist
*/
info(): DirectoryInfo;
interface DirectoryInfo {
/** Whether the directory exists */
exists: boolean;
/** Directory URI */
uri?: string;
/** Total size of directory contents in bytes */
size?: number;
/** Last modification time in milliseconds since epoch */
modificationTime?: number;
/** Creation time in milliseconds since epoch */
creationTime?: number;
/** Array of file names in the directory */
files?: string[];
}Usage Examples:
import { Directory, Paths } from "expo-file-system";
const userDataDir = new Directory(Paths.document, "user-data");
// Get comprehensive directory info
const info = userDataDir.info();
console.log(`Directory exists: ${info.exists}`);
if (info.size !== undefined) {
console.log(`Total size: ${(info.size / 1024 / 1024).toFixed(2)} MB`);
}
if (info.files) {
console.log(`Contains ${info.files.length} files:`);
info.files.forEach(filename => {
console.log(` - ${filename}`);
});
}
if (info.modificationTime) {
const lastModified = new Date(info.modificationTime);
console.log(`Last modified: ${lastModified.toLocaleDateString()}`);
}Platform-specific directory selection with native system pickers.
/**
* Opens a directory picker for user selection
* @param initialUri Optional initial directory path
* @returns Promise resolving to selected Directory instance
* @platform android
*/
static pickDirectoryAsync(initialUri?: string): Promise<Directory>;Usage Examples:
import { Directory } from "expo-file-system";
// Open directory picker (Android only)
try {
const selectedDir = await Directory.pickDirectoryAsync();
console.log(`User selected: ${selectedDir.uri}`);
// Work with selected directory
const contents = selectedDir.list();
console.log(`Selected directory contains ${contents.length} items`);
} catch (error) {
console.log("User cancelled directory selection");
}
// Open picker with initial location
const documentsDir = await Directory.pickDirectoryAsync("/storage/emulated/0/Documents");Internal validation methods for ensuring directory paths are valid.
/**
* Validates a directory path
* @hidden This method is not meant to be used directly
*/
validatePath(): void;Usage Examples:
import { Directory, Paths } from "expo-file-system";
// Path validation happens automatically in constructor
try {
const validDir = new Directory(Paths.document, "valid-name");
// Path validation successful
} catch (error) {
console.error("Invalid directory path:", error.message);
}
// Manual validation if needed
const customDir = new Directory("/custom/path/directory");
try {
customDir.validatePath();
console.log("Path is valid");
} catch (error) {
console.error("Path validation failed:", error.message);
}Common patterns for working with directory hierarchies and recursive operations.
Usage Examples:
import { Directory, File, Paths } from "expo-file-system";
// Recursive directory traversal
function traverseDirectory(dir: Directory, level = 0): void {
const indent = " ".repeat(level);
console.log(`${indent}📁 ${dir.name}/`);
const contents = dir.list();
contents.forEach(item => {
if (item instanceof File) {
console.log(`${indent} 📄 ${item.name} (${item.size} bytes)`);
} else if (item instanceof Directory) {
traverseDirectory(item, level + 1);
}
});
}
// Calculate total directory size
function calculateDirectorySize(dir: Directory): number {
let totalSize = 0;
const contents = dir.list();
contents.forEach(item => {
if (item instanceof File) {
totalSize += item.size;
} else if (item instanceof Directory) {
totalSize += calculateDirectorySize(item);
}
});
return totalSize;
}
// Find files by extension
function findFilesByExtension(dir: Directory, extension: string): File[] {
const results: File[] = [];
const contents = dir.list();
contents.forEach(item => {
if (item instanceof File && item.extension === extension) {
results.push(item);
} else if (item instanceof Directory) {
results.push(...findFilesByExtension(item, extension));
}
});
return results;
}
// Usage
const rootDir = new Directory(Paths.document);
traverseDirectory(rootDir);
const totalSize = calculateDirectorySize(rootDir);
console.log(`Total size: ${(totalSize / 1024 / 1024).toFixed(2)} MB`);
const jsonFiles = findFilesByExtension(rootDir, '.json');
console.log(`Found ${jsonFiles.length} JSON files`);