A comprehensive cross-platform package management abstraction library that enables developers to programmatically install, manage, and find packages across multiple package managers including npm, yarn, pnpm, bun for Node.js projects, and CocoaPods for iOS projects.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
CocoaPods integration for iOS and macOS projects with automatic CLI installation, intelligent error handling, and project detection.
Main class for managing CocoaPods operations in iOS/macOS projects.
class CocoaPodsPackageManager {
readonly name = 'CocoaPods';
constructor(options: { cwd: string; silent?: boolean });
/** Runs `pod install` and attempts to automatically run known troubleshooting steps */
installAsync(options?: { spinner?: Ora }): Promise<void>;
/** Check if CocoaPods CLI is installed */
isCLIInstalledAsync(): Promise<boolean>;
/** Install CocoaPods CLI non-interactively */
installCLIAsync(): Promise<boolean>;
/** Get CocoaPods version */
versionAsync(): Promise<string>;
/** Handle pod install errors with automatic remediation */
handleInstallErrorAsync(options: {
error: any;
spinner?: Ora;
shouldUpdate?: boolean;
updatedPackages?: string[];
}): Promise<SpawnResult>;
}Usage Examples:
import { CocoaPodsPackageManager } from '@expo/package-manager';
const podManager = new CocoaPodsPackageManager({
cwd: '/path/to/ios/project',
silent: false
});
// Install pods with automatic error handling
await podManager.installAsync();
// Check CLI status
const hasCocoaPods = await podManager.isCLIInstalledAsync();
if (!hasCocoaPods) {
await podManager.installCLIAsync();
}Class methods for project detection and CLI installation.
class CocoaPodsPackageManager {
/** Find the iOS/macOS project root containing a Podfile */
static getPodProjectRoot(projectRoot: string): string | null;
/** Check if a project uses CocoaPods */
static isUsingPods(projectRoot: string): boolean;
/** Check if CocoaPods CLI is available in the system */
static isCLIInstalledAsync(spawnOptions?: SpawnOptions): Promise<boolean>;
/** Check if CocoaPods is available for the current platform and project */
static isAvailable(projectRoot: string, silent: boolean): boolean;
/** Install CocoaPods CLI automatically using multiple methods */
static installCLIAsync(options: {
nonInteractive?: boolean;
spawnOptions?: SpawnOptions;
}): Promise<boolean>;
/** Install CocoaPods CLI using gem */
static gemInstallCLIAsync(
nonInteractive?: boolean,
spawnOptions?: SpawnOptions
): Promise<void>;
/** Install CocoaPods CLI using Homebrew */
static brewInstallCLIAsync(spawnOptions?: SpawnOptions): Promise<void>;
/** Link CocoaPods CLI using Homebrew */
static brewLinkCLIAsync(spawnOptions?: SpawnOptions): Promise<void>;
}Usage Examples:
// Project detection
const iosRoot = CocoaPodsPackageManager.getPodProjectRoot('/path/to/project');
const usesPods = CocoaPodsPackageManager.isUsingPods('/path/to/ios');
// Platform and availability checking
const available = CocoaPodsPackageManager.isAvailable('/path/to/project', false);
// CLI installation
if (!await CocoaPodsPackageManager.isCLIInstalledAsync()) {
await CocoaPodsPackageManager.installCLIAsync({
nonInteractive: true
});
}
// Manual installation methods
try {
await CocoaPodsPackageManager.gemInstallCLIAsync(true);
} catch (error) {
await CocoaPodsPackageManager.brewInstallCLIAsync();
}CocoaPods-specific error types and handling utilities.
type CocoaPodsErrorCode = 'NON_INTERACTIVE' | 'NO_CLI' | 'COMMAND_FAILED';
class CocoaPodsError extends Error {
readonly name = 'CocoaPodsError';
readonly isPackageManagerError = true;
constructor(
message: string,
public code: CocoaPodsErrorCode,
public cause?: Error
);
}
/** Extract missing dependency information from CocoaPods error output */
function extractMissingDependencyError(errorOutput: string): [string, string] | null;
/** Parse pod update messages from error output */
function getPodUpdateMessage(output: string): {
updatePackage: string | null;
shouldUpdateRepo: boolean;
};
/** Format CocoaPods repo update messages with helpful context */
function getPodRepoUpdateMessage(errorOutput: string): {
message: string;
updatePackage?: string;
shouldUpdateRepo?: boolean;
};
/** Format CocoaPods install errors with improved messaging and troubleshooting */
function getImprovedPodInstallError(
error: SpawnResult & Error,
options: { cwd?: string }
): Error;Usage Examples:
import {
CocoaPodsError,
extractMissingDependencyError,
getImprovedPodInstallError
} from '@expo/package-manager';
try {
await podManager.installAsync();
} catch (error) {
if (error instanceof CocoaPodsError) {
switch (error.code) {
case 'NO_CLI':
console.log('CocoaPods CLI not installed');
break;
case 'COMMAND_FAILED':
console.log('Pod command failed:', error.message);
break;
}
}
}
// Parse error information
const errorOutput = "Unable to find a specification for `expo-camera` depended upon by `expo-app`";
const [missing, dependent] = extractMissingDependencyError(errorOutput);
// missing: "expo-camera", dependent: "expo-app"The CocoaPods manager includes intelligent error handling and automatic remediation:
Automatic Repo Updates:
// Automatically detects when `pod install --repo-update` is needed
await podManager.installAsync(); // May internally run repo update if neededMissing Dependency Resolution:
// Automatically attempts to resolve missing dependencies
// by updating specific packages or running repo updates
try {
await podManager.installAsync();
} catch (error) {
// Error handling includes specific remediation steps
const improvedError = getImprovedPodInstallError(error, { cwd: projectRoot });
console.log(improvedError.message); // Contains helpful troubleshooting steps
}CLI Installation Fallbacks:
// Tries multiple installation methods automatically
await CocoaPodsPackageManager.installCLIAsync({
nonInteractive: true
});
// 1. Attempts gem install
// 2. Falls back to brew install
// 3. Attempts brew link if needed
// 4. Provides clear error messages if all methods failCocoaPods manager can detect iOS/macOS projects in different locations:
// Checks multiple possible locations:
// 1. projectRoot/Podfile (direct)
// 2. projectRoot/ios/Podfile (React Native style)
// 3. projectRoot/macos/Podfile (macOS projects)
const podRoot = CocoaPodsPackageManager.getPodProjectRoot('/path/to/project');
if (podRoot) {
const podManager = new CocoaPodsPackageManager({ cwd: podRoot });
await podManager.installAsync();
}CocoaPods is macOS-only and requires proper platform detection:
// Automatically checks platform and project compatibility
const available = CocoaPodsPackageManager.isAvailable(projectRoot, false);
// Returns false if:
// - Not running on macOS
// - No Podfile found in project or ios/macos subdirectories