Parser utility for xcodeproj/project.pbxproj files that allows editing and writing back Xcode project files
Build target management including creating new targets, managing target dependencies, and configuring target-specific build settings for iOS, macOS, watchOS, and extension targets.
Create new build targets with automatic configuration and integration.
/**
* Add new build target to project
* Creates target with default Debug/Release configurations and proper setup
* @param {string} name - Target name
* @param {string} type - Target type (application, app_extension, framework, etc.)
* @param {string} subfolder - Target subfolder for organization
* @param {string} bundleId - Bundle identifier for the target
* @returns {object} Target object with UUID and configuration
*/
addTarget(name, type, subfolder, bundleId);Usage Examples:
// Create iOS app target
const appTarget = proj.addTarget('MyApp', 'application', 'MyApp', 'com.company.myapp');
console.log('Created app target:', appTarget.uuid);
// Create app extension target
const extensionTarget = proj.addTarget(
'MyExtension',
'app_extension',
'MyExtension',
'com.company.myapp.extension'
);
// Create framework target
const frameworkTarget = proj.addTarget('MyFramework', 'framework', 'MyFramework');
// Create watch app target
const watchTarget = proj.addTarget(
'MyWatchApp',
'watch2_app',
'MyWatchApp',
'com.company.myapp.watchkitapp'
);
// Create static library target
const libTarget = proj.addTarget('MyLibrary', 'static_library', 'MyLibrary');Manage dependencies between targets for proper build ordering.
/**
* Add target dependency relationship
* Ensures dependent targets are built before the main target
* @param {string} target - Target UUID that depends on others
* @param {string[]} dependencyTargets - Array of dependency target UUIDs
* @returns {object} Target object with updated dependencies
*/
addTargetDependency(target, dependencyTargets);Usage Examples:
// Make app depend on framework
const appTargetUuid = proj.getFirstTarget().uuid;
const frameworkTargetUuid = frameworkTarget.uuid;
proj.addTargetDependency(appTargetUuid, [frameworkTargetUuid]);
// Make watch extension depend on watch app
const watchExtensionTarget = proj.addTarget(
'MyWatchExtension',
'watch2_extension',
'MyWatchExtension'
);
proj.addTargetDependency(watchTarget.uuid, [watchExtensionTarget.uuid]);
// Multiple dependencies
const testTarget = proj.addTarget('MyTests', 'unit_test_bundle', 'MyTests');
proj.addTargetDependency(testTarget.uuid, [appTargetUuid, frameworkTargetUuid]);Find and access existing targets in the project.
/**
* Get first target in project
* @returns {object} Target object with UUID and target data
*/
getFirstTarget();
/**
* Find target by product type
* @param {string} productType - Product type to search for
* @returns {object|null} Target object or null if not found
*/
getTarget(productType);
/**
* Find target by name
* @param {string} name - Target name to search for
* @returns {object|null} Target object or null if not found
*/
pbxTargetByName(name);
/**
* Find target UUID by name
* @param {string} name - Target name to search for
* @returns {string|null} Target UUID or null if not found
*/
findTargetKey(name);Usage Examples:
// Get main app target
const mainTarget = proj.getFirstTarget();
console.log('Main target name:', mainTarget.firstTarget.name);
// Find target by name
const myTarget = proj.pbxTargetByName('MyFramework');
if (myTarget) {
console.log('Found target UUID:', proj.findTargetKey('MyFramework'));
}
// Find target by product type
const appTarget = proj.getTarget('com.apple.product-type.application');
const frameworkTarget = proj.getTarget('com.apple.product-type.framework');Manage target-specific attributes and capabilities.
/**
* Add target attribute (used for capabilities, team settings, etc.)
* @param {string} prop - Attribute property name
* @param {any} value - Attribute value
* @param {object} target - Target object (optional, defaults to first target)
*/
addTargetAttribute(prop, value, target);
/**
* Remove target attribute
* @param {string} prop - Attribute property name to remove
* @param {object} target - Target object (optional, defaults to first target)
*/
removeTargetAttribute(prop, target);Usage Examples:
// Add development team
proj.addTargetAttribute('DevelopmentTeam', 'ABCD123456');
// Add target-specific attribute
const extensionTarget = proj.pbxTargetByName('MyExtension');
proj.addTargetAttribute('SystemCapabilities', {
'com.apple.ApplicationGroups.iOS': { enabled: 1 }
}, extensionTarget);
// Add provisioning profile
proj.addTargetAttribute('ProvisioningStyle', 'Manual');
proj.addTargetAttribute('ProvisioningProfile', 'profile-uuid-here');
// Remove attribute
proj.removeTargetAttribute('DevelopmentTeam');/**
* Supported target types and their product types
*/
const TARGET_TYPES = {
'application': 'com.apple.product-type.application',
'app_extension': 'com.apple.product-type.app-extension',
'bundle': 'com.apple.product-type.bundle',
'command_line_tool': 'com.apple.product-type.tool',
'dynamic_library': 'com.apple.product-type.library.dynamic',
'framework': 'com.apple.product-type.framework',
'static_library': 'com.apple.product-type.library.static',
'unit_test_bundle': 'com.apple.product-type.bundle.unit-test',
'watch_app': 'com.apple.product-type.application.watchapp',
'watch2_app': 'com.apple.product-type.application.watchapp2',
'watch_extension': 'com.apple.product-type.watchkit-extension',
'watch2_extension': 'com.apple.product-type.watchkit2-extension'
};/**
* Target object structure
*/
interface Target {
/** Target UUID */
uuid: string;
/** PBXNativeTarget configuration */
pbxNativeTarget: {
/** Target type */
isa: 'PBXNativeTarget';
/** Target name */
name: string;
/** Product name */
productName: string;
/** Product reference UUID */
productReference: string;
/** Product type */
productType: string;
/** Build configuration list UUID */
buildConfigurationList: string;
/** Build phases array */
buildPhases: BuildPhaseReference[];
/** Build rules array */
buildRules: any[];
/** Dependencies array */
dependencies: DependencyReference[];
};
}
interface BuildPhaseReference {
/** Build phase UUID */
value: string;
/** Build phase type comment */
comment: string;
}
interface DependencyReference {
/** Dependency UUID */
value: string;
/** Dependency type comment */
comment: string;
}iOS App with Extension:
// Create main app
const mainApp = proj.addTarget(
'MyApp',
'application',
'MyApp',
'com.company.myapp'
);
// Create share extension
const shareExtension = proj.addTarget(
'ShareExtension',
'app_extension',
'ShareExtension',
'com.company.myapp.share'
);
// Set up dependency (app embeds extension)
proj.addTargetDependency(mainApp.uuid, [shareExtension.uuid]);
// Configure extension attributes
proj.addTargetAttribute('SystemCapabilities', {
'com.apple.ApplicationGroups.iOS': { enabled: 1 }
}, shareExtension);Framework with Tests:
// Create framework
const framework = proj.addTarget(
'MyFramework',
'framework',
'MyFramework',
'com.company.myframework'
);
// Create test bundle
const tests = proj.addTarget(
'MyFrameworkTests',
'unit_test_bundle',
'MyFrameworkTests',
'com.company.myframework.tests'
);
// Tests depend on framework
proj.addTargetDependency(tests.uuid, [framework.uuid]);
// Add test host if needed
proj.addTargetAttribute('TEST_HOST', '$(BUILT_PRODUCTS_DIR)/MyApp.app/MyApp', tests);watchOS App Setup:
// Create watch app
const watchApp = proj.addTarget(
'MyWatchApp',
'watch2_app',
'MyWatchApp',
'com.company.myapp.watchkitapp'
);
// Create watch extension
const watchExtension = proj.addTarget(
'MyWatchExtension',
'watch2_extension',
'MyWatchExtension',
'com.company.myapp.watchkitapp.watchkitextension'
);
// Set up dependencies
const mainApp = proj.getFirstTarget();
proj.addTargetDependency(mainApp.uuid, [watchApp.uuid]);
proj.addTargetDependency(watchApp.uuid, [watchExtension.uuid]);
// Configure watch-specific attributes
proj.addTargetAttribute('WATCHOS_DEPLOYMENT_TARGET', '6.0', watchApp);
proj.addTargetAttribute('WATCHOS_DEPLOYMENT_TARGET', '6.0', watchExtension);Multi-Platform Framework:
// Create iOS framework
const iosFramework = proj.addTarget(
'MyFramework-iOS',
'framework',
'MyFramework-iOS'
);
// Create macOS framework
const macosFramework = proj.addTarget(
'MyFramework-macOS',
'framework',
'MyFramework-macOS'
);
// Configure platform-specific settings
proj.addTargetAttribute('SUPPORTED_PLATFORMS', 'iphoneos iphonesimulator', iosFramework);
proj.addTargetAttribute('SUPPORTED_PLATFORMS', 'macosx', macosFramework);Development Team Setup:
// Add development team to all targets
const targets = [
proj.getFirstTarget(),
proj.pbxTargetByName('MyExtension'),
proj.pbxTargetByName('MyFramework')
];
targets.forEach(target => {
if (target) {
proj.addTargetAttribute('DevelopmentTeam', 'TEAM123456', target);
proj.addTargetAttribute('ProvisioningStyle', 'Automatic', target);
}
});Capability Configuration:
// Enable app groups for main app and extension
const capabilities = {
'com.apple.ApplicationGroups.iOS': { enabled: 1 },
'com.apple.BackgroundModes': { enabled: 1 },
'com.apple.Push': { enabled: 1 }
};
proj.addTargetAttribute('SystemCapabilities', capabilities);Install with Tessl CLI
npx tessl i tessl/npm-xcode