I opened Rork's Expo documentation page and the yellow warning box reached me before the prose did. You can no longer create Expo (React Native) projects in Rork. New apps are native iPhone in Swift, native Android in Kotlin, or web in React.
The sentence right after it was the one that mattered more. If you already have an Expo project, it keeps working — you can build it, publish it, and export it to GitHub exactly as before.
So this is not a story about something breaking. The door to starting one closed; the ones already running keep running. That makes the decision harder, not easier. You are being asked whether to rebuild something that is not broken.
I run my own apps as an indie developer, and this is the kind of choice where my hands stop moving. So let me lay out what actually changed, what did not, and how to decide on your own terms.
What changed, and what did not
The primary source is Rork's own page, "What happened to Expo?" New iPhone apps are Swift, new Android apps are Kotlin, and new web apps are React. The stated reason is direct: on Rork's internal benchmarks, the agent wrote better Swift apps than React Native apps.
The same page also notes that Expo is still a real native stack and that plenty of production apps ship that way. It is not written as a dismissal of Expo.
| Item | Current status |
|---|---|
| Creating a new Expo project | Not available |
| Building an existing Expo project | Works as before |
| Publishing an existing Expo project | Works as before |
| Exporting to GitHub | Works as before |
| New iPhone app | Swift (SwiftUI) |
| New Android app | Kotlin |
| New web app | React |
One honest caveat. The documentation carries no date for when this switch happened. Rork's docs are published without dates in the body, so I have nothing solid to point at for "since when." I am describing the current state only, not a timeline.
Rebuilding changes the shape of the project itself
The docs recommend moving an existing Expo project to Swift. Next to the preview there is an Add iOS app button. Press it and the agent recreates your screens, navigation, data flows, and design as a native iPhone app in SwiftUI. For Android, you use the + menu above the preview and pick Kotlin.
The part I found reassuring: your Expo app is not deleted. It stays in the same project, so you can hold the two side by side.
After a rebuild, the project looks like this:
- Two codebases. Swift for iPhone, Kotlin for Android. Not one shared file.
- One hosted backend. With Rork Cloud or Supabase, both apps talk to the same database.
- One chat, one context. "Add dark mode to both" reaches each app.
- One place to publish. App Store, Google Play, and web from the same Publish menu.
Then the docs say something I did not expect them to admit: the two apps can drift. A Swift change is not the same file as a Kotlin change, and the agent is what keeps them in sync. That is genuinely different from one shared React Native codebase.
I appreciated that they wrote it down. It is also, for me, where the decision actually lives.
When I was maintaining iOS and Android side by side on my own wallpaper app, I once fixed a piece of copy on one platform and not the other, and I did not notice for a long while. A missing feature announces itself. A drifted string, a different margin, a reordered list — those only surface when you open both at once. Drift does not crash, so nothing tells you about it.
Four questions that decide it
This is not a question of which stack is better. For me it came down to four things.
| Question | Leans toward staying | Leans toward rebuilding |
|---|---|---|
| Do you ship Android too? | Yes, or you plan to | iPhone only for now |
| Can you pause shipping? | Review or launch dates are stacked up | There is room before the next update |
| Do you need widgets, Live Activities, or sensors? | Not for a while | Now, or soon |
| Do you read and edit the code yourself? | Yes, you export and work in it | Mostly you leave it to the agent |
On the third row: Rork's comparison page describes Swift as the path to home screen widgets, Live Activities, advanced motion and body tracking, AR, better game performance, and finer sensor access. If you have business in that territory, rebuilding is a shortcut rather than a detour.
If instead you ship Android in parallel and work in the code yourself, the cost of carrying two codebases arrives first. I wrote about a related decision — whether you need Rork Max at all — in Whether You Need Rork Max Is Answered by Your Permissions, Not the Price Page. The reasoning here follows the same shape.
Inventory your screens before you rebuild
Even if you decide to rebuild, do one thing before pressing the button: get a list of your current screens into your own hands.
The agent will recreate them. But deciding whether it succeeded is your job, and judging requires something to compare against.
In the exported Expo project:
# Write out the list of screens (routes) in the Expo project.
# Capture this before you press rebuild — it becomes your comparison sheet.
cd path/to/exported-expo-project
find app -name '*.tsx' -not -name '_*' \
| sed 's|^app/||; s|\.tsx$||; s|/index$||' \
| sort > screens.txt
wc -l screens.txtExpected output is a single line:
14 screens.txt
Screen names alone are not enough, so take one more step.
# Turn each route into a row with the four states worth checking.
# Columns: normal / empty / network failure / permission denied
while read -r r; do
printf '%s\t-\t-\t-\t-\n' "$r"
done < screens.txt > rebuild_checklist.tsv
head -3 rebuild_checklist.tsvWhich gives you:
(tabs)/home - - - -
(tabs)/settings - - - -
detail/[id] - - - -
Here is why the four states matter. What goes missing in a rebuild is rarely a screen. Screens are loud; you notice an absent one immediately. What goes missing lives between the screens.
When I rebuilt my own wallpaper app, the thing I missed longest was the offline state. The list rendered. Detail views opened. But with no connection, the screen simply said nothing at all, and I found that out much later than I would like to admit. A bug you can watch happen is easier to catch than a bug where nothing happens.
With this sheet, you can fill in cells one at a time while the rebuilt app is open. Until all four columns are filled, I treat the move as unfinished.
Either way, get it onto GitHub first
Whichever way you go, there is one step worth doing up front: export the current Expo code to GitHub and mark it.
# Mark the state you can come back to, before any rebuild.
git tag expo-before-swiftui-rebuild
git push origin expo-before-swiftui-rebuild
# Confirm the tag landed.
git tag --list 'expo-*'Output:
expo-before-swiftui-rebuild
The tag is less about rolling back and more about having something to compare with. When you are staring at the SwiftUI version wondering "was it always like this?", one reliable place to open the old code shortens the wondering considerably.
If this is the first time the exported code goes into git, write the .gitignore before you run git init — I collected that order of operations in Write .gitignore Before You Run git init on an Exported Rork Project. For what happens after the move, from SwiftUI build through delivery, Native iOS Apps with Rork Max: SwiftUI to TestFlight covers adjacent ground.
How I would decide
If you have an Expo project, ship Android as well, and your next update is close, I would stay where I am for now. There is not yet enough reason to stop something that works.
If you ship iPhone only, you have business with widgets or Live Activities, and there is room before the next release, I lean toward rebuilding. Knowing the Expo version stays inside the same project turned out to be more reassuring than I expected. It is not a one-way door.
And whichever you choose, one thing gets decided first. Before deciding whether to move, decide what you will compare afterward. That order is the one I try hardest not to break on the days I am in a hurry.
Start by writing out the routes in your app directory and giving each one four columns. Whether to rebuild can wait until you have looked at that sheet.
Thank you for reading this far. I hope it gives you a concrete first move rather than one more thing to weigh.