Registry / devops / pbxproj-dom

pbxproj-dom

JSON →
library1.2.0jsnpmunverified

pbxproj-dom is a JavaScript/TypeScript library designed to parse and manipulate Xcode's `project.pbxproj` files, providing a Document Object Model (DOM) for programmatic access. It aims to offer a JavaScript API similar to Cocoapods' Ruby-based project modification capabilities. The current stable version is 1.2.0, released in April 2019. The project appears to be in maintenance mode, with infrequent updates since its last major release. Its primary differentiator is enabling direct, code-driven modifications to Xcode project settings and configurations without requiring manual interaction with Xcode itself, facilitating automation of tasks such as setting build configurations, managing signing styles, or modifying build settings within a Node.js environment.

npm install pbxproj-dom
INSTALL
IMPORT
SIG · PBXPROJ-DOM
P
pbxproj-dom
devopsjavascriptv1.2.0
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Xcode
import { Xcode } from 'pbxproj-dom/xcode';
const Xcode = require('pbxproj-dom/xcode');
The library primarily uses ES module syntax. Direct CommonJS `require` for named exports might not work as expected, and the main `Xcode` class is explicitly exported from a specific subpath, not the root package.
Xcode (type)
import type { Xcode } from 'pbxproj-dom/xcode';
For TypeScript projects, use `import type` for type-only imports to ensure they are stripped from the JavaScript output, preventing potential bundling or runtime issues in environments that don't support type imports.

Demonstrates how to programmatically open an Xcode `project.pbxproj` file, access its main project object, retrieve build configurations, and read specific build settings like `SWIFT_VERSION`. This runnable example dynamically creates a minimal valid `pbxproj` file for testing purposes.

import { Xcode } from 'pbxproj-dom/xcode'; import path from 'path'; import fs from 'fs'; // Define paths for a dummy Xcode project for demonstration const dummyProjectPath = './temp-test.xcodeproj'; const dummyPbxprojPath = path.join(dummyProjectPath, 'project.pbxproj'); // Create the dummy project directory if it doesn't exist if (!fs.existsSync(dummyProjectPath)) { fs.mkdirSync(dummyProjectPath, { recursive: true }); } // A minimal, valid pbxproj content for testing purposes const minimalPbxprojContent = `// !$*UTF8*$!\n{ archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ /* End PBXFileReference section */ /* Begin PBXGroup section */ 08FB7C8017B03F0100B1A761 /* CustomFolder */ = { isa = PBXGroup; children = ( ); path = CustomFolder; sourceTree = "<group>"; }; mainGroup = 08FB7C8017B03F0100B1A761; /* End PBXGroup section */ /* Begin PBXProject section */ 08FB7C7917B03F0100B1A761 /* Project object */ = { isa = PBXProject; buildConfigurationList = 08FB7C7D17B03F0100B1A761 /* Build configuration list for PBXProject \"TestProject\" */; compatibilityVersion = \"Xcode 3.2\"; mainGroup = 08FB7C8017B03F0100B1A761; productRefGroup = 08FB7C8117B03F0100B1A761 /* Products */; projectDirPath = \"\"; projectRoot = \"\"; targets = ( ); }; /* End PBXProject section */ /* Begin XCBuildConfiguration section */ 08FB7C7E17B03F0100B1A761 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CODE_SIGN_ENTITLEMENTS = \"TestProject/TestProject.entitlements\"; CODE_SIGN_IDENTITY = \"Apple Development\"; \"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\"; ENABLE_BITCODE = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = \"TestProject/TestProject-Prefix.pch\"; INFOPLIST_FILE = \"TestProject/Info.plist\"; LD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\"; PRODUCT_BUNDLE_IDENTIFIER = com.example.testproject; PRODUCT_NAME = \"$(TARGET_NAME)\"; SWIFT_OPTIMIZATION_LEVEL = \"-Onone\"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = \"1,2\"; }; name = Debug; }; 08FB7C7F17B03F0100B1A761 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CODE_SIGN_ENTITLEMENTS = \"TestProject/TestProject.entitlements\"; CODE_SIGN_IDENTITY = \"Apple Development\"; \"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\"; ENABLE_BITCODE = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = \"TestProject/TestProject-Prefix.pch\"; INFOPLIST_FILE = \"TestProject/Info.plist\"; LD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\"; PRODUCT_BUNDLE_IDENTIFIER = com.example.testproject; PRODUCT_NAME = \"$(TARGET_NAME)\"; SWIFT_OPTIMIZATION_LEVEL = \"-Owholemodule\"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = \"1,2\"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 08FB7C7D17B03F0100B1A761 /* Build configuration list for PBXProject \"TestProject\" */ = { isa = XCConfigurationList; buildConfigurations = ( 08FB7C7E17B03F0100B1A761 /* Debug */, 08FB7C7F17B03F0100B1A761 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 08FB7C7917B03F0100B1A761 /* Project object */; }\n`; fs.writeFileSync(dummyPbxprojPath, minimalPbxprojContent); try { const xcode = Xcode.open(dummyPbxprojPath); console.log('Successfully opened pbxproj file.'); // Access the project object and its build configurations const project = xcode.project; const rootObject = project.objects[project.rootObject]; if (rootObject && rootObject.isa === 'PBXProject') { console.log(`Root Project Object Name (via productRefGroup): ${project.objects[rootObject.productRefGroup]?.name || 'Unknown'}`); const configListId = rootObject.buildConfigurationList; const configList = project.objects[configListId]; if (configList && configList.isa === 'XCConfigurationList') { // Find the Debug build configuration const debugConfigId = configList.buildConfigurations.find(configRef => project.objects[configRef]?.name === 'Debug'); if (debugConfigId) { const debugConfig = project.objects[debugConfigId]; console.log(`Debug SWIFT_VERSION: ${debugConfig.buildSettings.SWIFT_VERSION}`); // Example of modification (uncomment to run and save): // debugConfig.buildSettings.SWIFT_VERSION = '5.5'; // console.log(`Updated Debug SWIFT_VERSION to: ${debugConfig.buildSettings.SWIFT_VERSION}`); // xcode.save(); // Save changes back to the file // console.log('Modified SWIFT_VERSION and saved to ' + dummyPbxprojPath); } else { console.log('Debug configuration not found.'); } } } else { console.log('Root project object not found or incorrect type.'); } } catch (error) { console.error('Error processing pbxproj file:', error.message); } finally { // Clean up the dummy project file and directory if (fs.existsSync(dummyPbxprojPath)) { fs.unlinkSync(dummyPbxprojPath); } if (fs.existsSync(dummyProjectPath)) { fs.rmdirSync(dummyProjectPath); } console.log('Cleaned up dummy project files.'); }
Debug
Known issues
gotchaThe `pbxproj-dom` parser may struggle with `project.pbxproj` files generated by modern Xcode versions or those containing complex configurations, such as specific 'Expo Configure project' build phases. This can result in parsing errors during `Xcode.open()` calls.
fix
Manually inspect the `project.pbxproj` for unusual or complex sections, especially around shell scripts in build phases. If persistent parsing issues occur with modern project structures, consider using alternative, more actively maintained `pbxproj` parsing libraries.
affects: >=1.0.0
gotchaGiven its last release was in April 2019, `pbxproj-dom` may lack support for new features, build settings, and project structures introduced in Xcode versions released after that date. This limitation can impact its utility for projects that leverage recent Xcode capabilities, potentially leading to errors or incomplete modifications.
fix
Verify that the library supports the specific Xcode version and `pbxproj` format your project utilizes. For projects requiring newer Xcode features, manual modifications or an alternative parsing library might be necessary.
affects: >=1.0.0
Errors
Common errors & fixes
peg$SyntaxError: Expected "\"", "\'", "\\\"", "\\n", or [^\\"] but "\\" found.
This error typically occurs when the library's internal PEG.js parser encounters an unexpected character or an unsupported syntax within the `project.pbxproj` file. This is frequently triggered by complex or non-standard shell scripts in Xcode build phases, notably those generated by tools like Expo.
fix
Examine the `project.pbxproj` file around the reported line and column for unusual characters, particularly backslashes or complex escape sequences within shell scripts. Manual correction of the problematic `pbxproj` section or using a different parsing tool capable of handling the specific `pbxproj` format may resolve the issue.
Upgrade
Version history
1.2.0latest on npm
Audit
Dependencies

No dependency data recorded yet.

Agent activity
2 hits · last 30 days
node
2
Resources
pbxproj-dom — npm install pbxproj-dom · libregistry