◉RORK LABJP
●EXPO — EAS Observe now records native crashes (Oct 7). On SDK 57, update to 57.0.21 or later●RORK — GPT-6.1 Sol (Sep 29) and Claude Sonnet 5.5 (Sep 28) are now in the model menu●RN 0.88 — React Native 0.88.x is scheduled for Oct 12, 2 days left●Q&A — People keep asking why AuthSession returns no result in Android standalone builds●WINDOWS — A walkthrough shows how to ship an iPhone app from Windows only, with no Mac●NEW — When only notifications fail in Expo Go: three checks to run first●EXPO — EAS Observe now records native crashes (Oct 7). On SDK 57, update to 57.0.21 or later●RORK — GPT-6.1 Sol (Sep 29) and Claude Sonnet 5.5 (Sep 28) are now in the model menu●RN 0.88 — React Native 0.88.x is scheduled for Oct 12, 2 days left●Q&A — People keep asking why AuthSession returns no result in Android standalone builds●WINDOWS — A walkthrough shows how to ship an iPhone app from Windows only, with no Mac●NEW — When only notifications fail in Expo Go: three checks to run first
Articles/AI Models
◉ AI Models/2026-09-15Advanced

Where the AI decision lives once Rork splits your app into two native codebases

New Rork apps are Swift on iPhone and Kotlin on Android — two separate codebases. Here is how I decide which AI-related judgments stay in each client and which move to the shared backend, plus the minimal contract both clients read the same way.

Rork577Swift48Kotlin4architecture13AI featuresdesign decisions3

✦ Premium Article

I spent an evening adding an Android app to a project that had only ever been an iPhone app. I pressed the + above the preview, picked Android (Kotlin), and watched the agent rebuild the screens and the navigation one by one.

When it finished, the first thing I looked for was not the layout. I went looking for the line that decides how many items a free user gets to see.

I found it right next to the Kotlin screen. The same rule existed on the iPhone side too, written in Swift. Both were correct. Both worked. What stayed with me was only this: the same meaning now lived in two places.

What follows is not about building an AI feature. It is about drawing a line — which AI-related judgments stay in each client, and where the shared backend takes over. If you only have one platform today, there is still a line worth drawing now, so I will cover that too.

What split was not the screens. It was the conditionals

Let me set the ground first. Rork's documentation states plainly that new apps are Swift on iPhone, Kotlin on Android, and React on the web, and that existing Expo projects keep working as before (What happened to Expo?).

The same page carries a sentence I took more seriously than the rest: the two apps are separate codebases, a Swift change is not the same file as a Kotlin change, and the two can drift. What a single project shares is the backend, the chat, and the place you publish from — not the code itself (iPhone, Android, or web: what's the difference).

If you came from a single React Native codebase, this is where the mental model has to shift. That the screens doubled is obvious the moment you look at the preview. What is harder to see is that the conditionals doubled along with them.

In an app with AI features, those conditionals cluster. Which inputs go through and which are refused. How many calls remain today. Which model to use. How much of the response to keep. None of those are screens. They are judgments, and once a judgment lives twice, the answers start to diverge on the first day you only fix one side.

I wrote about the step before this one — whether to keep an Expo project or rebuild it — in Rork no longer creates new Expo projects. This piece picks up after the split.

The drift I hit first, in my own apps

As an indie developer I have run wallpaper apps for a long time. The iOS and Android sides were always separate native implementations, with only the delivered images and their metadata coming down from a shared server. In other words, I had already been living for years in the shape Rork now uses for new projects.

What actually broke was nothing dramatic. It was one line deciding whether a given image could be shown in a given region.

Early on I kept that check in the clients. The reasoning was simple: fewer round trips, faster screens. It did not go well. The day I added one exclusion condition to one implementation, I forgot the other. No crash. No error. The same image simply kept appearing on one platform only.

I found out because someone wrote in. The logs showed nothing unusual, because both sides were answering correctly according to the conditions each one held.

The line I drew that week has not moved since.

A judgment that stays quiet when it breaks does not belong in the client. If I make an exception, it has to be somewhere drift causes no real harm.

AI features carry this property even more strongly. Responses are supposed to differ every time, so "different" stops being a signal that anything is wrong. Two clients can run two different policies and return two different answers, and both will look perfectly reasonable.

✦

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 will be able to sort every AI-related judgment in your app into the ones that belong in each client and the ones that belong in the shared backend
✦You will be able to close the places that drift silently between Swift and Kotlin before the two sides start giving different answers
✦You will be able to lift a working decision-envelope implementation, read identically by Swift and Kotlin, straight into your own project
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 $15 for lifetime access
View Membership →

Related Articles

◉ AI Models2026-04-26
Use Apple FoundationModels in Rork — A Practical Guide to On-Device LLM Apps That Keep Working Offline
Call Apple's FoundationModels framework from a Rork-generated SwiftUI app to add AI features that keep working offline. Covers text generation, streaming, structured output via @Generable, and tool calling — all with full Swift code and production-ready error handling.
◉ AI Models2026-10-05
Sonnet 5.5, GPT-6.1 Sol, or Opus 5.5? I Decide by the Kind of Fix Before I Pick the Model. A Week of Logging Where My Rork Credits Went
After Rork's model menu settled into Sonnet 5.5, GPT-6.1 Sol, and Opus 5.5, I sorted my fixes into three kinds and assigned a model and effort level to each. Here is how I read the changelog, the tiny ledger that tracks where each credit goes, and the rule I drew from a week of entries.
◉ AI Models2026-09-28
Keep Fixing in the Same Thread, or Restore and Rephrase? What I Learned Fixing One Rork Bug Both Ways
When a Rork fix request fails for the third time, do you keep going or use Restore and ask differently? I fixed the same bug both ways and compared round trips, leftover code, and where I now draw the line.
📚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