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`);