or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

directory-operations.mdfile-operations.mdindex.mdnetwork-operations.mdpickers.mdstreaming.mdsystem-paths.md
tile.json

system-paths.mddocs/

System Directories and Paths

Access to system directories (cache, document, bundle) and comprehensive path manipulation utilities with cross-platform compatibility and Apple shared container support.

Capabilities

Paths Class

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;
}

System Directory Access

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

Disk Space Monitoring

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

Path Information Queries

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";
}

PathUtilities Methods

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"
// }

Platform-Specific Directory Patterns

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();
      }
    }
  });
}