or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

build-cache.mdconfiguration.mdindex.mdpaths.mdsdk-version.md
tile.json

paths.mddocs/

Path Resolution

Utilities for resolving entry points and file extensions in Expo projects, with support for monorepos, platform-specific files, and Metro bundler integration.

Capabilities

Entry Point Resolution

Resolve the main entry file for an Expo project based on package.json and platform requirements.

/**
 * Resolve the absolute entry file for an Expo project
 * Checks package.json main field, then index files, then expo/AppEntry
 * @param projectRoot - Project root directory
 * @param options - Platform and package.json overrides
 * @returns Absolute path to entry file
 */
function resolveEntryPoint(
  projectRoot: string,
  {
    platform,
    pkg,
  }?: {
    platform?: string;
    pkg?: PackageJSONConfig;
  }
): string;

/**
 * Resolve entry point relative to server or project root
 * Useful for Metro bundler which needs relative paths
 * @param projectRoot - Project root directory  
 * @param options - Platform and package.json overrides
 * @returns Relative path to entry file
 */
function resolveRelativeEntryPoint(
  projectRoot: string,
  {
    platform,
    pkg,
  }?: {
    platform?: string;
    pkg?: PackageJSONConfig;
  }
): string;

Usage Examples:

import { resolveEntryPoint, resolveRelativeEntryPoint } from "@expo/config/paths";

// Get absolute entry path
const entryPoint = resolveEntryPoint("/path/to/project");
// Result: "/path/to/project/index.js" or main field from package.json

// Platform-specific entry resolution
const iosEntry = resolveEntryPoint("/path/to/project", {
  platform: "ios"
});
// Looks for index.ios.js, index.native.js, then index.js

// Get relative path for Metro
const relativeEntry = resolveRelativeEntryPoint("/path/to/project");
// Result: "./index.js" (relative to Metro server root)

File Extension Handling

Generate appropriate file extensions for different platforms and language configurations.

/**
 * Get file extensions for bare workflow projects
 * @param platforms - Target platforms ('ios', 'android', 'web')
 * @param languageOptions - Language configuration options
 * @returns Array of file extensions in priority order
 */
function getBareExtensions(
  platforms: string[],
  languageOptions?: LanguageOptions
): string[];

/**
 * Get file extensions based on platforms, base extensions, and workflows
 * @param platforms - Target platforms array
 * @param extensions - Base file extensions (js, ts, etc.)
 * @param workflows - Workflow types (expo, bare, etc.)
 * @returns Combined extensions array
 */
function getExtensions(
  platforms: string[],
  extensions: string[],
  workflows: string[]
): string[];

/**
 * Get language extensions in priority order
 * @param options - Language configuration
 * @returns Extensions array (ts, tsx, js, jsx, mjs, etc.)
 */
function getLanguageExtensionsInOrder(options: LanguageOptions): string[];

interface LanguageOptions {
  /** Include TypeScript extensions */
  isTS: boolean;
  /** Include modern JavaScript extensions (mjs) */
  isModern: boolean;
  /** Include React extensions (jsx, tsx) */
  isReact: boolean;
}

Usage Examples:

import { getBareExtensions, getLanguageExtensionsInOrder } from "@expo/config/paths";

// Get extensions for iOS and Android with TypeScript
const extensions = getBareExtensions(['ios', 'android'], {
  isTS: true,
  isModern: true,
  isReact: true
});
// Result: ['ios.ts', 'ios.tsx', 'android.ts', 'android.tsx', 'native.ts', 'native.tsx', 'ts', 'tsx', 'js', 'jsx', 'mjs', 'json']

// Get language extensions only
const langExtensions = getLanguageExtensionsInOrder({
  isTS: true,
  isModern: false,
  isReact: true
});
// Result: ['ts', 'tsx', 'js', 'jsx']

File Resolution Utilities

Low-level utilities for finding files with various extensions.

/**
 * Statically resolve a file with extensions (no node module resolution)
 * @param fromDirectory - Directory to search in
 * @param moduleId - Base filename or path
 * @param extensions - Extensions to try
 * @returns Full path to file or null if not found
 */
function getFileWithExtensions(
  fromDirectory: string,
  moduleId: string,
  extensions: string[]
): string | null;

Usage Examples:

import { getFileWithExtensions } from "@expo/config/paths";

// Find a file with various extensions
const configFile = getFileWithExtensions(
  "/path/to/project",
  "app.config",
  ["js", "ts", "json"]
);
// Looks for app.config.js, app.config.ts, app.config.json

Metro Integration

Utilities for Metro bundler configuration in monorepo environments.

/**
 * Get the Metro server root directory for monorepos
 * Returns workspace root if found, otherwise project root
 * @param projectRoot - Project root directory
 * @returns Metro server root directory
 */
function getMetroServerRoot(projectRoot: string): string;

/**
 * Get workspace globs for Metro's watchFolders configuration
 * @param monorepoRoot - Monorepo root directory
 * @returns Array of glob patterns or null
 */
function getMetroWorkspaceGlobs(monorepoRoot: string): string[] | null;

/**
 * Convert absolute entry point to server root relative path
 * @param projectRoot - Project root directory
 * @param absolutePath - Absolute path to convert
 * @returns Relative path from Metro server root
 */
function convertEntryPointToRelative(
  projectRoot: string,
  absolutePath: string
): string;

Usage Examples:

import { 
  getMetroServerRoot, 
  getMetroWorkspaceGlobs,
  convertEntryPointToRelative 
} from "@expo/config/paths";

// Get Metro server root for monorepo
const serverRoot = getMetroServerRoot("/path/to/workspace/packages/app");
// Result: "/path/to/workspace" (workspace root)

// Get workspace globs for Metro watchFolders
const globs = getMetroWorkspaceGlobs("/path/to/workspace");
// Result: ["packages/*/src/**/*"] (example)

// Convert absolute to relative path
const relativePath = convertEntryPointToRelative(
  "/path/to/project",
  "/path/to/project/src/index.js"
);
// Result: "src/index.js"

Path Utilities

General-purpose path manipulation utilities.

/**
 * Ensure a path has or doesn't have a trailing slash
 * @param inputPath - Path to modify
 * @param needsSlash - Whether slash is needed
 * @returns Path with correct trailing slash
 */
function ensureSlash(inputPath: string, needsSlash: boolean): string;

/**
 * Get the possible project root (current working directory)
 * @returns Absolute path to current working directory
 */
function getPossibleProjectRoot(): string;

Usage Examples:

import { ensureSlash, getPossibleProjectRoot } from "@expo/config/paths";

// Ensure trailing slash
const withSlash = ensureSlash("/path/to/dir", true);
// Result: "/path/to/dir/"

const withoutSlash = ensureSlash("/path/to/dir/", false);
// Result: "/path/to/dir"

// Get current project root
const projectRoot = getPossibleProjectRoot();
// Result: "/current/working/directory"

Path Resolution Types

interface PackageJSONConfig {
  dependencies?: Record<string, string>;
  main?: string;
  name?: string;
  version?: string;
  [key: string]: any;
}

interface LanguageOptions {
  /** Include TypeScript extensions (.ts, .tsx) */
  isTS: boolean;
  /** Include modern JavaScript extensions (.mjs) */
  isModern: boolean;
  /** Include React extensions (.jsx, .tsx) */
  isReact: boolean;
}

Error Handling

Path resolution functions may throw ConfigError with specific error codes:

// Thrown when entry point cannot be resolved
throw new ConfigError(
  "Cannot resolve entry file: The main field defined in your package.json points to an unresolvable or non-existent path.",
  'ENTRY_NOT_FOUND'
);

// Thrown when no entry point is found
throw new ConfigError(
  "The project entry file could not be resolved. Define it in the main field of the package.json, create an index.js, or install the expo package.",
  'ENTRY_NOT_FOUND'
);