RORK LABJP
BUILD — Rork Max runs real Macs in the cloud loaded with Xcode and the iOS SDK, writing SwiftUI, compiling, reading the errors and building again. That loop, not the code generation, is what lifts the outputNATIVE — What comes out is pure Swift and SwiftUI, not React Native. Reaching AR, Metal graphics and widgets that React Native cannot touch is the real gap between this and other buildersPLATFORMS — Coverage spans iPhone, iPad, Apple Watch, Apple TV and Vision Pro, plus iMessage. Worth a look if you want to start from a watch app or an extension rather than a phone screenCOMPANION — The Rork Companion app lets you check a generated build on a real iPhone without a paid Apple Developer account, lowering the bar for trying a first project end to endPRICING — Free to start, paid plans from $25 a month, and Rork Max on the $200 Max plan. Worth working out up front how many projects it takes to earn that backDEADLINE — From August 31, 2026, Google Play requires target API level 36 or higher for new apps and updates alike. Ten days out, and the targetSdkVersion of what you generate is yours to verifyBUILD — Rork Max runs real Macs in the cloud loaded with Xcode and the iOS SDK, writing SwiftUI, compiling, reading the errors and building again. That loop, not the code generation, is what lifts the outputNATIVE — What comes out is pure Swift and SwiftUI, not React Native. Reaching AR, Metal graphics and widgets that React Native cannot touch is the real gap between this and other buildersPLATFORMS — Coverage spans iPhone, iPad, Apple Watch, Apple TV and Vision Pro, plus iMessage. Worth a look if you want to start from a watch app or an extension rather than a phone screenCOMPANION — The Rork Companion app lets you check a generated build on a real iPhone without a paid Apple Developer account, lowering the bar for trying a first project end to endPRICING — Free to start, paid plans from $25 a month, and Rork Max on the $200 Max plan. Worth working out up front how many projects it takes to earn that backDEADLINE — From August 31, 2026, Google Play requires target API level 36 or higher for new apps and updates alike. Ten days out, and the targetSdkVersion of what you generate is yours to verify
Articles/Dev Tools
Dev Tools/2026-08-16Advanced

Find the Code That Trips App Store 2.5.2 Before You Submit

If a remote value can change what your app does, Guideline 2.5.2 may apply. Here is where the line actually sits, plus a script that surfaces the risky paths in your repo before submission.

App Store87App Review2Expo175React Native227Remote Config9

Premium Article

There is one moment that always makes me pause: adding a new key to remote config.

Changing a color from the server is fine. Swapping out an entire screen from the server is a different animal. The wallpaper apps I run ship their catalog and their copy from a backend, and the wider that remote surface gets, the smoother operations become — right up until review.

In March 2026, Apple blocked App Store updates for Replit and Vibecode. The cited basis was Guideline 2.5.2, and the reported issue was that both let users generate code and then run it inside the reviewed app (Apple Blocks Updates for AI Vibe Coding Apps in App Store).

If you ship apps built with Rork, that story is closer to home than it looks. Nothing stops you from letting an AI write your code. What can stop you is leaving a path where code gets executed inside the app — and that path can slip in without anyone deciding to add it.

What follows is a way to surface those paths mechanically, with the script I actually ran and what running it taught me about its own blind spots.

2.5.2 is about whether behavior changes, not where code comes from

Start with the text. Guideline 2.5.2 says apps should not "download, install, or execute code which introduces or changes features or functionality of the app, including other apps" (App Review Guidelines).

The easy misread is the subject. What is prohibited is not downloading code. What is prohibited is introducing or changing functionality by doing so.

You can confirm that reading by working backward from the carve-outs. JavaScript running inside WebKit is fine under this rule. Educational apps may, under conditions, download code for students to run. Neither exception would make sense if the rule were a blanket ban on remote code.

I had this wrong for a while myself. I designed as if anything fetched from a server was suspect. The real line is narrower and more specific.

What arrives from the serverWhat happens in the appThrough the 2.5.2 lens
Wallpaper catalog JSONThe list shows different itemsData swap. Behavior is unchanged
A Remote Config thresholdAn existing branch is taken differentlyInside the reviewed feature set
An EAS Update JS bundleThe implementation is replaced wholesaleInterpreted-layer update. An accepted practice
An expression string passed to evalNew logic comes into existence at runtimeIntroduces functionality
A dynamic import from a remote URLCode nobody reviewed runsIntroduces functionality

Rows three and four are where the rule becomes legible. An EAS Update replaces your entire JS bundle. By volume, that dwarfs handing one line of text to eval. Yet the first is an established workflow and the second is the thing that gets apps pulled.

The boundary is not drawn around delivery. It is drawn around whether the app can exceed the feature set that was reviewed. OTA updates are treated as replacing the implementation of an app that keeps the same purpose and the same features. eval leaves an opening for logic that nobody had seen at review time. It is a question of scope, not of bytes.

Once you hold it that way, decisions get fast. Adding something new, ask yourself: am I delivering, or am I generating? The answer usually arrives on the spot.

Six implementations that cross the line

Here is the scan target. At indie scale, these are the six that realistically show up. The first three should be gone before you submit; the last three are fine to keep if you can explain what feeds them.

  1. eval(...) — runs a string as code
  2. new Function(...) — treated the same as eval. Hand-rolled expression evaluators love this one
  3. import("https://...") — pulls a remote module at runtime
  4. injectedJavaScript — JS injected into a WebView. A constant is fine; a string from your server is not
  5. source={{ html: ... }} — a path for rendering arbitrary HTML
  6. A map that picks a screen from a remote value, like components[remote.screen]

Items four through six are not on the "delete it" list because they are legitimate, widespread patterns. Rendering help content in a WebView is normal. Reordering tabs from remote config is normal. The problem only appears when the value flowing in comes from outside and its contents are not fixed ahead of time.

So treat these six as a list of places to trace an input back to its source, not a list of things to remove on sight.

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
You can tell which parts of your own codebase could fall under 2.5.2, reading it straight from the source before you submit
You can draw the line in your own design between what a remote value may change (data, settings) and what it must not (the behavior itself)
You avoid the scramble of ripping out features after a rejection, so your launch date survives a period when review times are long
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-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-08-20
A beta-SDK build can reach TestFlight, but it can't reach review
Builds made with a beta Xcode can be distributed through TestFlight, but they cannot be submitted for App Store review. Here is how to check which SDK produced your build, and how to protect your release profile in eas.json.
Dev Tools2026-08-17
When an Expo UI drop-in swap actually removes a dependency
Expo UI went stable in SDK 56 with drop-in replacements for eight community packages. Swapping one import does not always shrink your dependency list. Here is how to decide which swaps actually pay off, straight from the dependency graph.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →