◉RORK LABJP
●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SDK 58 — Beta since 09/15 with no stable date yet; running projects in Expo Go has required login since 09/03●WIDGET — A write-up traces an iOS widget that renders black only in production builds●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SDK 58 — Beta since 09/15 with no stable date yet; running projects in Expo Go has required login since 09/03●WIDGET — A write-up traces an iOS widget that renders black only in production builds●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…
Articles/Dev Tools
⬡ Dev Tools/2026-05-30Advanced

Managing Native Settings Across Rork-Exported Apps with a Custom Expo Config Plugin

Tired of re-typing your AdMob ID and ATT string every time prebuild wipes your Info.plist? Here is how I made native settings reproducible with a custom Expo config plugin and shared it across six wallpaper apps.

Rork585Expo219config plugin6AdMob73prebuild3

✦ Premium Article

The week after I wired AdMob into an app exported from Rork, I added another library and ran npx expo prebuild. The GADApplicationIdentifier I had hand-written into Info.plist the previous week was simply gone. Of course it was — the whole ios/ folder gets regenerated. But I didn't know that at the time, so I wrote it back, watched it vanish, and repeated that a few times.

I have been building apps solo since 2014, and the wallpaper apps that grew to 50 million cumulative downloads now run as six parallel titles. Typing the same AdMob bootstrap by hand six times is nothing but a breeding ground for mistakes. I once pasted the wrong App ID into a single app and shipped a release where no ads showed at all. A custom Expo config plugin is what finally removed this "hand-edits that linger in the native layer" problem at the root.

Why your native settings vanish on every prebuild

The whole appeal of Rork and Expo is that you rarely think about ios/ and android/. Those native folders are output, not source. From the declarations in app.config.ts and package.json, npx expo prebuild regenerates the native projects from scratch every time.

Miss this and you will struggle endlessly. Editing the generated ios/MyApp/Info.plist by hand is like writing in sand — the next prebuild washes it away. If you keep ios/ and android/ in .gitignore for a more managed workflow, this is doubly true.

The right mental model is that native settings should also be generated from declarations. A config plugin is the bridge between that declaration and the generated output. Both of my grandfathers were temple carpenters, and growing up watching them cut wood exactly to the drawing left me with a deep preference for state that can be reproduced from the same procedure. A config plugin gives native settings exactly that reproducibility.

How a config plugin works inside prebuild

A config plugin is a function that rewrites native files midway through prebuild, using a set of "mods" provided by @expo/config-plugins. The common ones are:

  • withInfoPlist — receives the iOS Info.plist as a JS object and lets you mutate it
  • withEntitlementsPlist — handles iOS entitlements such as Associated Domains
  • withAndroidManifest — exposes AndroidManifest.xml as a parsed object
  • withAppBuildGradle — edits the app/build.gradle string directly
  • withDangerousMod — a last resort for touching any file directly

Prebuild applies these mods in order, then writes out the native project. So instead of editing Info.plist by hand, you write a JS instruction that says "always put this value in, every time you prebuild."

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦A complete config plugin that injects your AdMob App ID, ATT string, and SKAdNetwork list during prebuild
✦A shared-module setup so one edit propagates native settings to all six apps at once
✦Real production gotchas: withDangerousMod idempotency, mod ordering, and why plugins never run on EAS Update
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

⬡ Dev Tools2026-07-28
Counting what prebuild --clean will erase before you upgrade to Expo SDK 57
A raw diff between two generated ios/ trees showed 649 changed lines; only 3 were real edits. How to count what prebuild --clean erases, and move it into a config plugin.
⬡ Dev Tools2026-06-12
Building a Developer Debug Menu Into Your Rork App — Verify Ads, Purchases, and Remote Config Before Release
A production-safe developer debug menu for Rork apps — switch environments, force test ads, simulate entitlements, and override Remote Config, with working TypeScript code and the pitfalls I hit running six apps.
⬡ Dev Tools2026-10-15
When EXPO_PUBLIC_ Values Read Fine in Dev but Come Back undefined in Production: Telling the Spellings Apart
The API URL reads fine while developing and turns undefined once the app is built. The cause was how process.env was written. I lined up babel-preset-expo's output for dev and production and tabulated which spellings get replaced and which are left behind.