Skip to content

create-app: Podfile patch leaves invalid Ruby on Expo prebuild projects #702

@TomKalina

Description

@TomKalina

Summary

Migrating an Expo (CNG / expo prebuild) project into Rock via npm create rock produces a syntactically broken ios/Podfile that breaks every subsequent build, both via Rock and via direct pod install.

What happens

After running npm create rock in an Expo project with a prebuilt ios/, line 42 of ios/Podfile becomes:

config = use_native_modules!(['npx', 'rock', 'config', '-p', 'ios'])(config_command)

This is two consecutive call expressions with no operator between them — Ruby parser refuses it:

[!] Invalid `Podfile` file: syntax error found
  42 | ... (config_command)
     |     ^ unexpected '(', expecting end-of-input

Every subsequent rock run:ios (and a manual pod install) then fails:

■  Failed: Installing CocoaPods dependencies
■  RockError: CocoaPods installation failed.

Root cause

packages/create-app/src/lib/utils/initInExistingProject.ts, function updatePodfile:

const replaced = content.replace(
  /(config\s*=\s*use_native_modules!)(\s*)/g,
  "$1(['npx', 'rock', 'config', '-p', 'ios'])$2",
);

The regex matches config = use_native_modules! plus any whitespace after the ! — it does not consume an existing argument list.

  • Community-CLI template Podfile: config = use_native_modules! (no argument) → regex inserts Rock's argument, result is well-formed. Works.
  • Expo prebuild template Podfile: config = use_native_modules!(config_command) (Expo passes its own autolinking command in as an argument) → regex matches only the prefix config = use_native_modules!, inserts (['npx', 'rock', 'config', '-p', 'ios']) right before the existing (config_command), leaving the latter on the line as a leftover. Broken Ruby.

Steps to reproduce

  1. Any Expo project with ios/ generated by expo prebuild (SDK 55 here, but the Expo template has shipped use_native_modules!(config_command) for a long time).
  2. npm create rock (selects iOS platform).
  3. Open ios/Podfile → broken line 42.
  4. pnpm rock run:ios (or pod install directly) → fails with the syntax error above.

Suggested fix

Make the regex consume the existing argument tuple so it gets replaced in full:

const replaced = content.replace(
  /(config\s*=\s*use_native_modules!)(\s*\([^)]*\))?/g,
  "$1(['npx', 'rock', 'config', '-p', 'ios'])",
);

The optional group (\s*\([^)]*\))? matches an existing parenthesized argument list (Expo's case) and lets it be replaced; on Community-CLI Podfiles it matches nothing, behaviour is unchanged.

The trailing-whitespace capture ($2 in the old regex) is not actually needed — whitespace before the next token survives because the regex doesn't consume it.

Why this matters

The Rock README points existing Community-CLI teams at npm create rock as the migration path. Expo (CNG) is currently the recommended starting point for new React Native projects, and many existing teams have already migrated to it. For those teams the migrator silently produces a broken Podfile that they then have to manually unbreak (and re-fix on every expo prebuild --clean, because ios/ is regenerated and gitignored).

A one-character regex change makes npm create rock Just Work on Expo projects too.

Environment

  • Rock: 0.13.0
  • Expo: SDK 55.0.23
  • React Native: 0.83.6
  • pnpm: 10.30.0
  • Node: 22.14.0
  • macOS, Apple Silicon

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions