or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

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

configuration.mddocs/

Configuration Management

Core functionality for reading, parsing, and modifying Expo project configurations. Supports both static (JSON) and dynamic (JavaScript/TypeScript) configuration files with plugin integration and validation.

Capabilities

Reading Configuration

Read and evaluate the complete configuration for an Expo project.

/**
 * Evaluate the config for an Expo project.
 * Supports app.config.js/ts (dynamic) and app.json/app.config.json (static)
 * @param projectRoot - Root folder containing application code
 * @param options - Configuration options for reading
 * @returns Complete project configuration with defaults applied
 */
function getConfig(projectRoot: string, options?: GetConfigOptions): ProjectConfig;

interface GetConfigOptions {
  /** Return only public-facing options, omitting private keys */
  isPublicConfig?: boolean;
  /** Preserve config mods for compilation (used in eject command) */
  isModdedConfig?: boolean;
  /** Skip SDK version requirement validation */
  skipSDKVersionRequirement?: boolean;
  /** Skip resolving plugins */
  skipPlugins?: boolean;
  /** Enable strict validation */
  strict?: boolean;
}

interface ProjectConfig {
  /** Fully evaluated Expo config with default values injected */
  exp: ExpoConfig;
  /** Dynamic config for processing native files during generation */
  mods?: ModConfig | null;
  /** Project package.json object with default values injected */
  pkg: PackageJSONConfig;
  /** Unaltered static config (app.config.json, app.json, or custom) */
  rootConfig: AppJSONConfig;
  /** Path to static json config file if it exists */
  staticConfigPath: string | null;
  /** Path to app.config.js or app.config.ts if it exists */
  dynamicConfigPath: string | null;
  /** Type of value exported from dynamic config ('function' | 'object' | null) */
  dynamicConfigObjectType: string | null;
  /** True if both static and dynamic configs exist with potential conflicts */
  hasUnusedStaticConfig: boolean;
}

Usage Examples:

import { getConfig } from "@expo/config";

// Basic configuration reading
const config = getConfig("/path/to/expo-project");
console.log("App name:", config.exp.name);
console.log("Platforms:", config.exp.platforms);

// Public config only (safe for hosting)
const publicConfig = getConfig("/path/to/expo-project", {
  isPublicConfig: true
});
// privateKeys, _internal, etc. are removed

// Skip SDK version requirement for incomplete projects
const configWithoutSDK = getConfig("/path/to/expo-project", {
  skipSDKVersionRequirement: true
});

Package.json Access

Read the package.json file with default values applied.

/**
 * Read package.json for an Expo project with defaults applied
 * @param projectRoot - Root folder containing package.json
 * @returns Package.json content with name and version defaults
 */
function getPackageJson(projectRoot: string): PackageJSONConfig;

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

Configuration File Paths

Get the paths to static and dynamic configuration files.

/**
 * Get the static and dynamic config paths for a project
 * @param projectRoot - Project root directory
 * @returns Object containing paths to config files
 */
function getConfigFilePaths(projectRoot: string): ConfigFilePaths;

interface ConfigFilePaths {
  /** Path to app.json or app.config.json */
  staticConfigPath: string | null;
  /** Path to app.config.js or app.config.ts */
  dynamicConfigPath: string | null;
}

Modifying Configuration

Attempt to modify an Expo project configuration programmatically.

/**
 * Attempt to modify an Expo project config.
 * Only works fully with static configs. Dynamic configs return warnings.
 * @param projectRoot - Project root directory
 * @param modifications - Partial config changes to apply
 * @param readOptions - Options for reading current config
 * @param writeOptions - Options for writing config
 * @returns Result indicating success, warning, or failure
 */
function modifyConfigAsync(
  projectRoot: string,
  modifications: Partial<ExpoConfig>,
  readOptions?: GetConfigOptions,
  writeOptions?: WriteConfigOptions
): Promise<{
  type: 'success' | 'warn' | 'fail';
  message?: string;
  config: ExpoConfig | null;
}>;

interface WriteConfigOptions {
  /** If true, changes are validated but not written */
  dryRun?: boolean;
}

Usage Examples:

import { modifyConfigAsync } from "@expo/config";

// Modify app name and version
const result = await modifyConfigAsync("/path/to/project", {
  name: "New App Name",
  version: "2.0.0"
});

if (result.type === 'success') {
  console.log("Config updated successfully");
} else {
  console.log("Warning:", result.message);
}

// Dry run to test changes
const dryResult = await modifyConfigAsync(
  "/path/to/project",
  { name: "Test Name" },
  {},
  { dryRun: true }
);

Utility Functions

Helper functions for extracting information from configurations.

/**
 * Get web build output path from configuration
 * @param config - Configuration object (optional)
 * @returns Web build output directory path
 */
function getWebOutputPath(config?: { [key: string]: any }): string;

/**
 * Extract app and web names from configuration
 * @param exp - Configuration object
 * @returns Object with appName and webName properties
 */
function getNameFromConfig(exp?: Record<string, any>): {
  appName?: string;
  webName?: string;
};

/**
 * Determine if project uses managed or bare workflow
 * @param projectRoot - Project root directory
 * @param exp - Optional config to check SDK version
 * @returns 'managed' or 'bare'
 */
function getDefaultTarget(
  projectRoot: string,
  exp?: Pick<ExpoConfig, 'sdkVersion'>
): ProjectTarget;

/**
 * Get descriptive name of project config type
 * @param projectRoot - Project root directory
 * @returns Human-readable config description
 */
function getProjectConfigDescription(projectRoot: string): string;

/**
 * Get config description with specific paths
 * @param projectRoot - Project root directory
 * @param projectConfig - Config file paths
 * @returns Human-readable config description
 */
function getProjectConfigDescriptionWithPaths(
  projectRoot: string,
  projectConfig: ConfigFilePaths
): string;

Configuration Types

// Main configuration interface (extensive, showing key properties)
interface ExpoConfig {
  name?: string;
  slug?: string;
  version?: string;
  sdkVersion?: string;
  platforms?: Platform[];
  description?: string;
  privacy?: 'public' | 'unlisted';
  primaryColor?: string;
  backgroundColor?: string;
  
  // Platform-specific configurations
  ios?: {
    bundleIdentifier?: string;
    buildNumber?: string;
    config?: any;
    // ... many more iOS-specific options
  };
  
  android?: {
    package?: string;
    versionCode?: number;
    config?: any;
    // ... many more Android-specific options  
  };
  
  web?: {
    build?: {
      output?: string;
    };
    name?: string;
    // ... web-specific options
  };
  
  // Plugin and build configuration
  plugins?: any[];
  hooks?: Hook[];
  
  // Updates configuration
  updates?: {
    enabled?: boolean;
    fallbackToCacheTimeout?: number;
    codeSigningCertificate?: string;
    codeSigningMetadata?: any;
    // ... updates options
  };
  
  // Internal properties (removed in public configs)
  _internal?: {
    projectRoot?: string;
    dynamicConfigPath?: string;
    staticConfigPath?: string;
    packageJsonPath?: string;
  };
}

interface AppJSONConfig {
  expo: ExpoConfig;
  [key: string]: any;
}

// Context for dynamic configuration evaluation
interface ConfigContext {
  projectRoot: string;
  staticConfigPath: string | null;
  packageJsonPath: string | null;
  config: Partial<ExpoConfig>;
}

// Hook system types
interface Hook {
  file: string;
  config: any;
}

type HookType = 'postPublish' | 'postExport';

interface HookArguments {
  config: any;
  url: any;
  exp: ExpoConfig;
  iosBundle: string | Uint8Array;
  iosSourceMap: string | null;
  iosManifest: any;
  iosManifestUrl: string;
  androidBundle: string | Uint8Array;
  androidSourceMap: string | null;
  androidManifest: any;
  androidManifestUrl: string;
  projectRoot: string;
  log: (msg: any) => void;
}

// Project privacy settings
enum ProjectPrivacy {
  PUBLIC = 'public',
  UNLISTED = 'unlisted'
}