npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

nexjax

v1.0.3

Published

Automatically configure iOS project settings (Team ID, version, display name, build number, iPhone-only) for React Native projects

Readme

Nexjax

A lightweight tool to automatically configure iOS project settings for React Native projects. Works with any React Native project (Expo, bare React Native, etc.).

Features

  • Auto-configure Team ID - Sets DEVELOPMENT_TEAM in Xcode project
  • Auto-fill Version - Updates CFBundleShortVersionString from app.json (Expo) or package.json (bare RN)
  • Auto-fill Build Number - Updates CFBundleVersion from app.json or config
  • Auto-fill Display Name - Updates CFBundleDisplayName from app.json or package.json
  • iPhone-only Support - Removes iPad orientations automatically
  • Zero Dependencies - Pure Node.js, no external dependencies
  • Works with any RN project - Supports both Expo (app.json) and bare React Native (package.json only)

Installation

As a dev dependency:

npm install --save-dev nexjax

Or use npx (no installation needed):

npx nexjax

Quick Start

1. First Time Setup

  1. Get your Team ID:

    • Open Xcode → Settings → Accounts
    • Select your Apple ID
    • Copy your Team ID (format: ABC123DEF4)
  2. Run the tool:

    npx nexjax YOUR_TEAM_ID

    Or if installed locally:

    npx nexjax YOUR_TEAM_ID
  3. Edit ios.config.json (created automatically):

    {
      "teamId": "YOUR_TEAM_ID",
      "version": "1.0.0",
      "displayName": "MyApp",
      "buildNumber": "1",
      "iphoneOnly": true,
      "permissions": {
        "NSPhotoLibraryUsageDescription": "We need access to your photos...",
        "NSCameraUsageDescription": "We need access to your camera..."
      }
    }

    Note: For Expo projects, permission strings can also be set in app.jsonexpo.ios.infoPlist and nexjax will automatically read them!

2. Configure Permission Strings (Optional)

For Expo projects, add permissions in app.json:

{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSPhotoLibraryUsageDescription": "We need access to your photos...",
        "NSCameraUsageDescription": "We need access to your camera..."
      }
    }
  }
}

For bare RN projects, add permissions in ios.config.json:

{
  "permissions": {
    "NSPhotoLibraryUsageDescription": "We need access to your photos...",
    "NSCameraUsageDescription": "We need access to your camera..."
  }
}

3. After Building iOS Project

After running npx expo prebuild or any iOS build command:

npx nexjax

Or add to your build scripts in package.json:

{
  "scripts": {
    "ios:build": "react-native run-ios && npx nexjax",
    "ios:configure": "npx nexjax"
  }
}

Configuration

Config File: ios.config.json

The tool creates ios.config.json in your project root with these settings:

{
  "teamId": "ABC123DEF4",
  "bundleIdentifier": "com.example.app",
  "version": "1.0.0",
  "displayName": "MyApp",
  "buildNumber": "1",
  "iphoneOnly": true,
  "permissions": {
    "NSPhotoLibraryUsageDescription": "We need access to your photos...",
    "NSCameraUsageDescription": "We need access to your camera...",
    "NSMicrophoneUsageDescription": "We need access to your microphone..."
  }
}

Auto-sync with app.json / package.json

The tool automatically reads from configuration files:

For Expo projects (with app.json):

  • expo.version → Used for CFBundleShortVersionString
  • expo.name → Used for CFBundleDisplayName
  • expo.ios.buildNumber → Used for CFBundleVersion
  • expo.ios.supportsTablet → Determines iPhone-only setting
  • expo.ios.infoPlist.* → Permission strings (all optional)

For bare React Native projects (package.json only):

  • package.json.version → Used for CFBundleShortVersionString
  • package.json.name → Used for CFBundleDisplayName

Permission Strings (Optional)

Nexjax can automatically configure iOS permission strings in Info.plist. Each permission is optional - only add the ones you need.

Configuration Priority:

  1. ios.config.jsonpermissions (always works, overrides app.json)
  2. app.jsonexpo.ios.infoPlist (Expo projects only)

For Expo projects: Can use either app.json or ios.config.json (or both - ios.config.json overrides) For bare RN projects: Use ios.config.jsonpermissions (no app.json available)

Supported permission keys:

  • NSPhotoLibraryUsageDescription - Photo library access
  • NSPhotoLibraryAddUsageDescription - Save photos to library
  • NSCameraUsageDescription - Camera access
  • NSMicrophoneUsageDescription - Microphone access
  • NSLocationWhenInUseUsageDescription - Location when in use
  • NSLocationAlwaysUsageDescription - Location always
  • NSContactsUsageDescription - Contacts access
  • NSCalendarsUsageDescription - Calendar access
  • NSRemindersUsageDescription - Reminders access
  • NSMotionUsageDescription - Motion & Fitness
  • NSHealthShareUsageDescription - Health data read
  • NSHealthUpdateUsageDescription - Health data write
  • NSBluetoothPeripheralUsageDescription - Bluetooth (deprecated, use NSBluetoothAlwaysUsageDescription)
  • NSBluetoothAlwaysUsageDescription - Bluetooth always
  • NSSpeechRecognitionUsageDescription - Speech recognition
  • NSFaceIDUsageDescription - Face ID
  • NSAppleMusicUsageDescription - Apple Music
  • NSSiriUsageDescription - Siri
  • NSUserTrackingUsageDescription - App Tracking Transparency

Priority Order

For all settings (version, displayName, buildNumber, etc.):

  1. ios.config.json - Primary source (can override everything)
  2. app.json (Expo) or package.json (bare RN) - Source of truth
  3. Command line argument - Overrides Team ID only

For permission strings specifically:

  1. ios.config.jsonpermissions - Always works (Expo & bare RN)
  2. app.jsonexpo.ios.infoPlist - Expo projects only (if no ios.config.json permissions)

Note:

  • If app.json exists, it takes priority over package.json for version/name
  • If no app.json, nexjax reads from package.json (bare RN projects)
  • Permission strings work the same way: ios.config.json always works, app.json is optional (Expo only)

Usage Examples

Basic Usage

# Configure with Team ID
npx nexjax YOUR_TEAM_ID

# Re-configure (uses saved Team ID from config)
npx nexjax

With npm scripts

{
  "scripts": {
    "prebuild:ios": "cd ios && pod install",
    "postbuild:ios": "npx nexjax",
    "rebuild:ios": "npm run prebuild:ios && npm run postbuild:ios"
  }
}

With Expo

{
  "scripts": {
    "prebuild:ios": "npx expo prebuild --platform ios --clean",
    "postbuild:ios": "npx nexjax",
    "rebuild:ios": "npm run prebuild:ios && npm run postbuild:ios"
  }
}

What It Does

1. Team ID Configuration

  • Updates DEVELOPMENT_TEAM in ios/*.xcodeproj/project.pbxproj
  • Preserves across rebuilds

2. Version & Build Number

  • Updates CFBundleShortVersionString in Info.plist
  • Updates CFBundleVersion in Info.plist

3. Display Name

  • Updates CFBundleDisplayName in Info.plist

4. iPhone-Only

  • Removes UISupportedInterfaceOrientations~ipad from Info.plist
  • Ensures app only runs on iPhone

5. Permission Strings (Optional)

  • Updates permission strings in Info.plist
  • Reads from app.json (Expo) or ios.config.json (bare RN)
  • Only configures permissions that are provided (all optional)

Project Structure

Expo Projects:

your-project/
├── app.json              ← Source of truth (version, name, buildNumber)
├── package.json
├── ios/                  ← Generated by expo prebuild
│   ├── YourApp.xcodeproj/
│   │   └── project.pbxproj
│   └── YourApp/
│       └── Info.plist
└── ios.config.json       ← Created automatically (Team ID, overrides)

Bare React Native Projects:

your-project/
├── package.json          ← Source of truth (version, name)
├── ios/
│   ├── YourApp.xcodeproj/
│   │   └── project.pbxproj
│   └── YourApp/
│       └── Info.plist
└── ios.config.json       ← Created automatically (Team ID, buildNumber, overrides)

Troubleshooting

"ios directory not found"

  • Make sure you're in the React Native project root
  • Run from the directory containing ios/ folder

"Xcode project not found"

  • Make sure you've built the iOS project at least once
  • For Expo: Run npx expo prebuild --platform ios first

"Info.plist not found"

  • The tool will search for Info.plist automatically
  • If not found, Team ID configuration will still work

Team ID not persisting

  • Make sure ios.config.json has teamId set
  • Run the tool again after rebuilding iOS project

API

Programmatic Usage

const { configureIOS } = require('nexjax');

// Configure with Team ID
await configureIOS('/path/to/project', 'YOUR_TEAM_ID');

// Re-configure (uses config file)
await configureIOS('/path/to/project');

License

MIT

Contributing

Contributions welcome! This is a simple tool designed to be lightweight and dependency-free.