React Native ist unglaublich leicht misszuverstehen, wenn man hauptsächlich aus der Webentwicklung kommt. Man schreibt Standard-React-Komponenten, verwendet JavaScript oder TypeScript, führt einen vertraut wirkenden Entwicklungsserver aus und erhält unglaublich schnelle Aktualisierungsfunktionen. Da sich der Workflow so nah an der Entwicklung von React für das Web anfühlt, ist die Versuchung groß, React Native lediglich als Webanwendung zu betrachten, die ordentlich in eine mobile Hülle verpackt ist.
Dieses mentale Modell ist völlig falsch.
React Native erstellt echte native mobile Apps. Die Benutzeroberfläche wird grundsätzlich nicht in ein Browser-DOM gerendert. Es gibt keine div- oder span-Elemente, und schon gar keine versteckte Webseite, die vorgibt, eine Anwendung zu sein. Stattdessen beschreibt Ihr React-Code einfach eine native Oberfläche, und React Native fungiert als Engine, die diese Beschreibung in echte iOS- und Android-Komponenten übersetzt. Expo baut dann auf React Native auf, indem es die historisch rauen Kanten der mobilen Entwicklung glättet und native Konfiguration, Entwicklungs-Builds, dateibasiertes Routing, Over-the-Air-Updates, Cloud-Builds und einen optimierten Zugriff auf gängige Geräte-APIs bietet. Sobald man die Grenze zwischen der nativen Laufzeitumgebung und dem JavaScript-Bundle tiefgreifend verstanden hat, wird das gesamte Ökosystem deutlich weniger verwirrend.
React Native ist nicht React DOM
React für das Web rendert direkt in das Browser-DOM, während React Native in native UI-Primitive rendert, die vom Betriebssystem bereitgestellt werden.
| React web | React Native |
|---|---|
div | View |
span or p | Text |
img | Image |
| Browser-DOM | Native iOS- und Android-Ansichten |
Wenn man so etwas schreibt:
<View style={{ backgroundColor: "red" }}>
<Text>Hello</Text>
</View>React Native generiert unter der Haube kein HTML. Unter iOS werden native UIKit-Ansichten erstellt, und unter Android native Android-Ansichten. Dieser strukturelle Unterschied ist von immenser Bedeutung für Leistung, Styling, Barrierefreiheit, Gesten, native Module und die Bereitstellung. Man liefert keine Website aus; man liefert eine kompilierte native Anwendung aus, deren Verhalten nur zufällig von einer JavaScript-Engine gesteuert wird.
Die zwei Programme in jeder React Native App
Das wichtigste Konzept, das man in React Native verstehen muss, ist, dass eine App in Wirklichkeit aus zwei separaten Programmen besteht, die nahtlos zusammenarbeiten.
Ihre mobile App
Native Laufzeitumgebung <-> JavaScript-BundleDie native Laufzeitumgebung ist die kompilierte App selbst. Sie ist in plattformnativen Sprachen geschrieben und wird streng mit nativen Tools erstellt. Unter iOS umfasst dies Xcode, Swift und Objective-C. Unter Android bedeutet dies, sich auf Gradle, Kotlin und Java zu verlassen. Umgekehrt ist das JavaScript-Bundle Ihr tatsächlicher React-Anwendungscode, der Ihre Bildschirme, Komponenten, Navigationshierarchie, Zustandsverwaltung und übergreifende Geschäftslogik enthält.
Die native Laufzeitumgebung beherbergt die JavaScript-Engine, benutzerdefinierte native Module, Berechtigungen, Anwendungsmetadaten, App-Symbole, Startbildschirme und die wichtige Brücke, die es JavaScript ermöglicht, mit nativen APIs zu kommunizieren. Sie ist kompiliert, signiert, plattformspezifisch und vor allem kann sie auf dem Gerät eines Benutzers nicht ohne ein formelles natives Update über den App Store geändert werden. Das JavaScript-Bundle ist weitaus flexibler. Während der Entwicklung kann es nahtlos über ein lokales Netzwerk direkt von Ihrem Computer geladen werden. In der Produktion wird es normalerweise sicher in die App-Binärdatei gebündelt, aber mit Over-the-Air-Updates kann es oft im laufenden Betrieb aktualisiert werden, ohne dass eine vollständige App-Store-Überprüfung erforderlich ist.
Die Browser-Analogie hilft hier oft: Die native Laufzeitumgebung ist wie der Chrome-Browser, während das JavaScript-Bundle wie die Website ist. Man kann Updates für eine Website endlos pushen, ohne dass der Benutzer Chrome aktualisieren muss. Wenn man jedoch eine brandneue Browserfunktion benötigt, die Chrome fehlt, muss der Browser selbst zwangsläufig aktualisiert werden.
Was tatsächlich einen nativen Rebuild erfordert
Diese grundlegende Aufteilung erklärt eine der häufigsten Ursachen für Reibung und Verwirrung bei Neueinsteigern: warum einige Änderungen sofort auf dem Bildschirm aktualisiert werden, während andere frustrierenderweise einen vollständigen nativen Rebuild erfordern.
| Änderung | Nativer Rebuild nötig? | OTA-Update möglich? |
|---|---|---|
| UI-Text anpassen | Nein | Ja |
| Neuen Bildschirm hinzufügen | Nein | Ja |
| Geschäftslogik korrigieren | Nein | Ja |
| Reine JavaScript-Bibliothek hinzufügen | Nein | Ja |
| Native Bibliothek hinzufügen | Ja | Nein |
| App-Symbol ändern | Ja | Nein |
| Berechtigungen ändern | Ja | Nein |
Wenn sich die Änderung ausschließlich auf JavaScript auswirkt, kann sie in der Regel sofort aktualisiert werden und kommt allgemein für ein Over-the-Air (OTA) Update in Frage. Wenn sich die Änderung jedoch auf native Gerätefunktionen, Systemberechtigungen, Binärmetadaten auswirkt oder neue native Module einführt, benötigen Sie unbedingt einen neuen nativen Build. Das Beherrschen dieser einzigen Regel erklärt fast jede Entscheidung im Entwicklungs-Workflow im React Native-Ökosystem.
Was Expo hinzufügt
Expo ist eine umfassende Plattform, die gezielt auf React Native aufbaut. Sie bietet von Haus aus eine viel vollständigere Entwicklungsumgebung und verbirgt gekonnt den Großteil der nativen Build-Komplexität, bis man tatsächlich damit interagieren muss.
In einem von Expo verwalteten Projekt sieht man die traditionellen Ordner ios/ und android/ fast nie. Stattdessen konfiguriert man das native Verhalten elegant über app.json, app.config.js, intelligente Config-Plugins und verschiedene installierte Pakete. Wenn es schließlich an der Zeit ist, die Anwendung zu erstellen, kann Expo über einen einzigen Befehl sauber die erforderlichen nativen Projekte für Sie generieren:
npx expo prebuildDieser mächtige Befehl erstellt die nativen ios/- und android/-Projekte vollständig basierend auf Ihrer High-Level-Konfiguration und den aufgelisteten Abhängigkeiten. Expo bietet auch stark getestete native Module, hervorragende Entwicklungstools, dateibasiertes Routing über den Expo Router, EAS Build für verwaltete Cloud-Builds, EAS Submit für die automatisierte Einreichung im App Store und EAS Update für die Bereitstellung von Over-the-Air JavaScript-Updates. Der grundlegende Punkt ist nicht, dass Expo nativen Code aus der Existenz tilgt – es verwaltet lediglich dessen Komplexität in Ihrem Namen.
Expo Go vs. Development Builds
Expo Go ist eine äußerst praktische, vorgefertigte App, die aktiv vom Expo-Team gepflegt wird. Man installiert sie direkt aus dem App Store, führt npx expo start auf seinem Rechner aus, scannt einen QR-Code mit dem Telefon, und Expo Go lädt sofort Ihr JavaScript-Bundle. Sie ist phänomenal, um React Native zu lernen und Ideen schnell als Prototyp zu entwickeln, da man nichts nativ kompilieren muss, bevor man die funktionierende App auf einem physischen Gerät sieht.
Die Haupteinschränkung besteht darin, dass Expo Go nur die spezifischen nativen Module enthält, die das Expo-Team bereits integriert hat. Man kann grundsätzlich nicht jede mögliche native Abhängigkeit, benutzerdefiniertes Verhalten von App-Symbolen, produktionsreife Splash-Screen-Mechaniken, Universal Links oder komplexe Setups für Remote-Push-Benachrichtigungen nativ darin testen.
Ein Development Build ist etwas völlig anderes. Es ist Ihre eigene dedizierte App-Binärdatei, die explizit für die Entwicklung erstellt wurde und in der die Bibliothek expo-dev-client installiert ist. Man kann sie sich leicht als eine eigene benutzerdefinierte Version von Expo Go vorstellen. Sie enthält tatsächlich die spezifischen nativen Module, die Ihre App in der Produktion für die Funktionsfähigkeit legitim benötigt.
| Funktion | Expo Go | Development Build |
|---|---|---|
| Einrichtung | Aus dem App Store installieren | Eigene App erstellen |
| Native Bibliotheken | Beschränkt auf die in Expo Go enthaltenen Module | Jede native Bibliothek, die Sie einbinden |
| App-Symbol und Splash | Nicht Ihre endgültige App | Ihre echte App-Konfiguration |
| Push-Benachrichtigungen | Eingeschränkt | Realistisches Testen |
| Bester Nutzen | Lernen und Prototypen | Ernsthafte App-Entwicklung |
Die praktische Regel ist bemerkenswert einfach: Beginnen Sie mit Expo Go, wenn es für Ihre aktuellen Anforderungen genügend Funktionalität bietet, aber wechseln Sie zu Development Builds, sobald Ihre App natives Verhalten oder Bibliotheken von Drittanbietern erfordert, die Expo Go schlichtweg nicht bereitstellen kann.
Entwicklung und Produktion laden JavaScript unterschiedlich
In einer Entwicklungsumgebung lädt Ihr physisches Telefon das JavaScript-Bundle normalerweise kontinuierlich von Metro herunter, dem lokalen Entwicklungsserver, der nahtlos auf Ihrem Computer ausgeführt wird.
Telefon, auf dem Expo Go oder ein Dev Build läuft
|
| fordert JavaScript-Bundle an
v
Metro-Entwicklungsserver auf Ihrem ComputerGenau dieser Mechanismus ist der Grund, warum Ihr Telefon und Ihr Computer typischerweise mit exakt demselben WLAN-Netzwerk verbunden sein müssen. Dies ist auch der zugrunde liegende Grund, warum Fast Refresh so wunderbar funktioniert – die App ruft kontinuierlich Code von einem aktiven Entwicklungsserver ab.
In der Produktion ändert sich die Architektur grundlegend. Das finale JavaScript-Bundle wird sicher in die App-Binärdatei selbst gepackt.
YourApp.apk oder YourApp.ipa
nativer Code
Assets
main.jsbundleDie Produktions-App muss offensichtlich keine Verbindung zu Ihrem lokalen Computer herstellen. Sie kann problemlos offline starten, und das JavaScript ist stark optimiert und explizit für Leistung gebündelt. EAS Update führt ein überzeugendes hybrides Modell ein. Die App wird anfangs mit einer sicher gebündelten JavaScript-Version ausgeliefert, aber beim Start kann sie im Hintergrund nach neueren JavaScript-Updates suchen und diese dynamisch auf dem Gerät zwischenspeichern. Diese Fähigkeit ist unglaublich leistungsstark, um Fehlerbehebungen und UI-Updates nahtlos auszuliefern, aber sie hat eine harte, unnachgiebige Grenze: OTA-Updates können absolut keine neuen nativen Funktionen oder Module hinzufügen.
Die Struktur eines Expo-Projekts
Ein von Expo verwaltetes Projekt ist typischerweise so strukturiert, dass reiner JavaScript-Code, übergreifende native Konfiguration, statische Assets und wesentliche Build-Konfigurationen sauber voneinander getrennt sind.
your-project/
app/ Bildschirme und Routen
components/ wiederverwendbare UI
hooks/ benutzerdefinierte Hooks
constants/ gemeinsame Werte
assets/ Bilder und Schriftarten
app.json native App-Konfiguration
package.json Abhängigkeiten
eas.json EAS-Build- und Update-KonfigurationDie Datei app.json steuert umfassend entscheidende Metadaten der nativen App.
{
"expo": {
"name": "My App",
"slug": "my-app",
"icon": "./assets/icon.png",
"android": {
"package": "com.company.myapp"
},
"ios": {
"bundleIdentifier": "com.company.myapp"
}
}
}Die Datei package.json ist von entscheidender Bedeutung, da die darin aufgeführten Abhängigkeiten häufig native Module enthalten können. Das Installieren eines reinen JavaScript-Pakets und das Installieren eines Pakets, das mit nativem Code gebündelt ist, sind fundamental unterschiedliche Aktionen mit völlig unterschiedlichen Auswirkungen auf Ihre Build-Pipeline.
React Native ist immer noch Frontend-Code
Obwohl React Native dafür sorgen kann, dass sich eine mobile App unglaublich nativ anfühlt, verwandelt es Frontend-Code ausdrücklich nicht auf magische Weise in Backend-Code. Eine React Native App sollte niemals direkt eine Verbindung zu einer Produktionsdatenbank herstellen. Sie sollte keine rohen Datenbank-Anmeldeinformationen enthalten und niemals private API-Geheimnisse in ihrem Bundle speichern. APK- und IPA-Dateien können von jedem trivial inspiziert werden, und JavaScript-Bundles können von böswilligen Akteuren leicht extrahiert werden.
Die korrekte, sichere Architektur bleibt genau dieselbe wie bei den meisten modernen Frontend-Systemen:
Mobile App <-> Backend API <-> DatenbankDie mobile App sollte ausschließlich über sicheres HTTPS mit Ihrer API kommunizieren. Ihre API handhabt dann sicher komplexe Authentifizierung, robuste Autorisierung, gründliche Validierung, strikte Ratenbegrenzung und privaten Datenbankzugriff. Die Datenbank bleibt vollständig privat und vor dem mobilen Client verborgen. Eine API-URL im Client-Code offenzulegen ist völlig normal, da Benutzer den Netzwerkverkehr von ihren eigenen Geräten aus ohnehin leicht abfangen und einsehen können. Echte Sicherheit entsteht nicht durch das Verbergen der API-URL; sie entsteht vollständig durch angemessene Authentifizierung, Autorisierung und strikte serverseitige Durchsetzung.
Backend-as-a-Service-Tools wie Supabase und Firebase halten sich weiterhin streng an dieses Muster. Der Client kommuniziert sicher mit einer zwischengeschalteten API-Schicht, ohne jemals direkt rohe Datenbank-Anmeldeinformationen mit unbegrenztem Zugriff zu verwenden. Beispielsweise ist der öffentliche anon-Schlüssel von Supabase explizit dafür konzipiert, dem Client sicher zugänglich gemacht zu werden, aber er muss zwangsläufig mit einer ordnungsgemäßen Authentifizierung und strenger Sicherheit auf Zeilenebene auf der Datenbankseite gekoppelt werden.
const supabase = createClient(
"https://xyz.supabase.co",
"public-anon-key"
);
const { data } = await supabase
.from("interviews")
.select("*");Die zugrunde liegende Sicherheit ergibt sich naturgemäß aus den strengen Richtlinien, die aktiv hinter der API ausgeführt werden, und nicht aus dem Vorwand, dass der clientseitige Schlüssel ein streng gehütetes Geheimnis sei.
Das mentale Modell, das man beibehalten sollte
Letztendlich ist React Native lediglich ein nativer Container, der eine hochleistungsfähige JavaScript-Anwendung ausführt. Expo fungiert als die robuste Plattform, die es erheblich einfacher macht, diesen Container zu konfigurieren, zu kompilieren, nahtlos zu aktualisieren und schließlich an die Benutzer auszuliefern. Expo Go ist ein enorm nützlicher, gemeinsam genutzter, vorgefertigter Container, während ein Development Build als Ihr eigener, vollständig maßgeschneiderter Container dient. Ein OTA-Update ändert auf einzigartige Weise das JavaScript, das innerhalb dieses Containers läuft, völlig getrennt vom Container selbst.
Sobald man diese Grenze klar erkennt und respektiert, ergibt das gesamte Ökosystem wesentlich mehr Sinn. Man versteht instinktiv, warum das Hinzufügen eines neuen Bildschirms sofort erfolgt, warum das Hinzufügen einer nativen Bibliothek einen neuen Build erfordert, warum Expo Go irgendwann für komplexe Apps nicht mehr ausreicht und warum mobile Apps zwangsläufig weiterhin ein sicheres, dediziertes Backend benötigen. Das ist die gesamte Lernkurve für React Native und Expo, komprimiert in ein einziges übergreifendes Konzept: Verstehen Sie, was sicher in JavaScript lebt, was streng in nativem Code lebt, und was genau die kritische Grenze zwischen ihnen überschreitet.
Referenzen
Mehr lesen
Architektur für zuverlässige mobile Abrechnung: Was ich auf die harte Tour gelernt habe
Ein Praxisblick auf die Reparatur von mobiler Abonnement-Abrechnung, wenn Webhooks, Sandbox-Käufe und Benutzeridentität versagen.
OAuth vs OIDC: Der Unterschied endlich erklärt
Eine praktische Erklärung von OAuth, OIDC, Access Tokens und ID Tokens ohne die übliche Authentifizierungs-Verwirrung.
Coder Tasks, Workspaces und OpenCode: Ein praktisches mentales Modell
Entwickeln Sie ein klareres mentales Modell für Coder Workspaces, Templates, Provisioners und KI-Programmieraufgaben.
