CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-expo--config

A library for interacting with the app.json configuration files in Expo projects

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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

docs

build-cache.md

configuration.md

index.md

paths.md

sdk-version.md

tile.json