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
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
xcode
✓ import xcode from 'xcode';
// Or for CommonJS:
const xcode = require('xcode');
✗ import { xcode } from 'xcode';
The `xcode` package primarily exposes a default export (or `module.exports` in CommonJS) which is an object containing the `project` method. Direct named imports are not supported. It is predominantly used via CommonJS `require` given its history and primary use case.
project
✓ const xcode = require('xcode');
const myProj = xcode.project(projectPath);
✗ import { project } from 'xcode';
The `project` function is a method on the default `xcode` export. It is not directly importable as a named export.
writeSync
✓ myProj.writeSync();
✗ xcode.writeSync(myProj);
`writeSync` is an instance method of an `xcode.project` object, used after modifications have been made to write changes back to the file system.
This quickstart demonstrates how to use `xcode` to parse an Xcode project file, add a source file, a header file, and a framework, and then write the changes back to the project file. It also includes setup and cleanup for a dummy project.
const xcode = require('xcode');
const fs = require('fs');
const path = require('path');
// Create a dummy Xcode project directory and file for demonstration
const projectDir = path.join(__dirname, 'myproject.xcodeproj');
const projectPath = path.join(projectDir, 'project.pbxproj');
if (!fs.existsSync(projectDir)) {
fs.mkdirSync(projectDir);
}
fs.writeFileSync(projectPath, `
// !$* PROJECT FILE *!$
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
1D6058900D05DD3D006BFB54 /* PBXProject */ = {
isa = PBXProject;
buildConfigurationList = 1D6058910D05DD3D006BFB54 /* Build configuration list for PBXProject */;
compatibilityVersion = 'Xcode 3.2';
has-SCM = 0;
mainGroup = 1D6058920D05DD3D006BFB54 /* CustomGroup */;
projectRoot = '';
targets = (
);
};
1D6058910D05DD3D006BFB54 /* Build configuration list for PBXProject */ = {
isa = XCConfigurationList;
buildConfigurations = (
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1D6058920D05DD3D006BFB54 /* CustomGroup */ = {
isa = PBXGroup;
children = (
);
sourceTree = '<group>';
};
};
rootObject = 1D6058900D05DD3D006BFB54 /* PBXProject */;
}
`);
const myProj = xcode.project(projectPath);
// Parsing is asynchronous and runs in a different process
myProj.parse(function (err) {
if (err) {
console.error('Error parsing project:', err);
return;
}
console.log('Project parsed successfully. Current targets:', myProj.pbxProject.targets.map(t => t.comment));
// Add a new source file (e.g., 'main.m')
myProj.addSourceFile('main.m', { sourceType: 'PBXFileReference' });
console.log('Added main.m to project.');
// Add a new header file (e.g., 'AppConfig.h')
myProj.addHeaderFile('AppConfig.h');
console.log('Added AppConfig.h to project.');
// Add a framework (e.g., 'CoreData.framework')
myProj.addFramework('CoreData.framework', { weak: true });
console.log('Added CoreData.framework to project.');
// Write the modified project back to the file
fs.writeFileSync(projectPath, myProj.writeSync());
console.log('Modified project written successfully.');
// Clean up the dummy project
fs.unlinkSync(projectPath);
fs.rmdirSync(projectDir);
console.log('Cleaned up dummy project directory.');
});
Debug
Known issues
gotchaThe package's API is described in its own README as "a bit wonky right now". Developers should be prepared for non-idiomatic JavaScript patterns or less intuitive method names.fixRefer to specific examples and the source code when facing unexpected behavior. Test changes thoroughly.
affects: >=1.0.0
breakingThe `xcode` package internally relies on a PEG.js grammar (`lib/parser/pbxproj.pegjs`) for parsing. If the Xcode project file format changes significantly with new Xcode versions, the parser might fail or produce incorrect results. Maintaining compatibility often requires updates to this grammar.fixMonitor the `cordova-node-xcode` GitHub repository for updates and check for new releases when encountering parsing issues with newer Xcode project formats. Consider contributing grammar fixes if possible.
affects: All versions, dependent on Xcode updates
breakingNode.js engine requirements for `xcode` and its parent project, `cordova-ios`, have increased over time. For example, `cordova-ios` 8.x requires Node.js >= 20.17.0. Using an older Node.js version may lead to installation or runtime issues.fixEnsure your Node.js environment meets the minimum version specified by the `engines` field in `package.json` for `xcode` and any dependent Cordova platforms. Use Node Version Manager (NVM) to easily switch Node.js versions.
affects: >=3.0.0 (and dependent Cordova versions)
gotchaThe `parse` method is asynchronous and runs in a different process. This means that any operations dependent on the parsed project data must be performed within its callback to ensure the project object is fully initialized.fixAlways encapsulate project modification logic inside the `myProj.parse(function (err, project) { ... });` callback to prevent race conditions or working with unparsed data. affects: >=1.0.0
Errors
Common errors & fixes
Error: Cannot find module 'xcode'
The package 'xcode' is not installed or not resolvable from the current working directory.
fixRun `npm install xcode` in your project directory.
TypeError: xcode.project is not a function
Attempting to use `xcode.project` before `xcode` is properly required or attempting to deconstruct `xcode` incorrectly.
fixEnsure `const xcode = require('xcode');` is used (for CommonJS) and access the `project` method as `xcode.project()`. Do not try `import { project } from 'xcode';` as it's not a named export. Error: ENOENT: no such file or directory, open 'myproject.xcodeproj/project.pbxproj'
The specified `projectPath` does not point to an existing `project.pbxproj` file.
fixVerify that the `projectPath` variable correctly points to the `project.pbxproj` file within an `.xcodeproj` bundle. Ensure the file exists at that location.
Parsing error: Expected "/*", "//", "$", "\"", "'", "(", "<*", "<", or a non-whitespace character but "\uFEFF" found.
The `project.pbxproj` file contains an unexpected character, often a Byte Order Mark (BOM), or is malformed in a way that the PEG.js parser cannot handle.
fixInspect the `project.pbxproj` file for hidden characters (e.g., using a hex editor or a text editor that shows unicode characters). If a BOM is present, remove it. If the file is malformed, attempt to fix it manually or regenerate it using Xcode if possible.
Audit
Dependencies
node-plistrequiredRequired for parsing and manipulating Apple .plist files, which are integral to Xcode project files.
qrequiredA promise library used internally for asynchronous operations, particularly for the parsing process.