Your web skills, one step closer to the user's pocket: native apps (Swift/Kotlin) and cross-platform (React Native/Flutter) — same ship-it habits.
← / → to navigate · EN/VI switch below
Not a URL — a bundle of code + assets that lives on the device.
The app is downloaded from a store (or a link) and runs on the device itself — with or without internet.
NATIVE: written in the platform's own language (Swift on iOS, Kotlin on Android). CROSS-PLATFORM: written once, wrapped for both (React Native, Flutter).
Code → build → run on a device or emulator → see it → change it. The dev loop is identical to web — the target is just a phone.
Same reactive idea as the web: the screen is a function of state. Change the state, the UI re-renders — whether it's a browser tab or a phone.
The whole mobile decision in one slide.
Swift for iOS, Kotlin for Android. Fastest, most polished, full access to every piece of hardware — but TWO codebases, two languages, two app stores.
Choose it when the platform IS the product.
React Native (JSX) or Flutter (Dart): write once, ship to both stores. About 90–95% of the native experience for most apps.
Choose it when being everywhere matters most.
Four options cover 99% of real mobile work.
iOS, iPadOS, macOS. Modern, safe, fast; the only way to a first-class Apple app. Xcode is the IDE.
The official Android language: concise, Java-friendly, null-safe. Android Studio is the IDE.
Full hardware access (camera, GPS, sensors, push), the best performance, and the store's recommended tooling.
Two codebases and two languages for two stores — double the work, double the review queues.
Your web skills, on a phone: JavaScript + JSX rendering to REAL native widgets. Expo is the easiest on-ramp.
Google's toolkit: a Dart codebase that draws its OWN UI (not native widgets). One pixel-perfect look on every screen.
One codebase, both stores. Hot reload: save a file and see it on the device in a second. Big, mature ecosystems.
The last 5–10% of polish, and occasional friction with brand-new hardware features (native modules bridge the gap).
| Swift | Kotlin | React Native | Flutter | |
|---|---|---|---|---|
| Road | Native (iOS) | Native (Android) | Cross | Cross |
| UI style | Native Apple widgets | Native Android widgets | Real native widgets via JS | Draws its own UI |
| Stores | App Store | Google Play | Both / Cả hai | Both / Cả hai |
| Best for | Premium iOS-first products | Premium Android-first products | JS shops, fast MVPs | Pixel-perfect, both platforms |
Save the file → the running app updates in a second, without a full rebuild. The dev loop gets 10x faster.
An emulator is a phone inside a program — fine for most work, but battery, camera and real lag only exist on real hardware.
JS gets bundled; Dart gets compiled (AOT) to machine code. The store gets a signed package: .ipa / .apk / .aab.
useState in React Native, setState in Flutter: the same reactive contract you met on the web, enforced by the framework.
This is your web React knowledge — View and Text are just the app's div and p.
import { useState } from "react";
export default function App() {
const [count, setCount] = useState(0);
return (
<View style={styles.box}>
<Text>Tap count: {count}</Text>
<Button title="Tap" onPress={() => setCount(count + 1)} />
</View>
);
}
State change → screen re-renders — the same contract as the web, now on a phone.
Flutter builds the screen as a tree of Widgets — the UI is code, drawn by the engine.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("Hello, mobile")
)
);
}
}
Scaffold → Center → Text: three widgets, one screen. That's the whole pattern.
Expo points your phone at your laptop; flutter builds and pushes to the device.
Meta's JS framework + the Expo toolchain — the fastest way for a JS developer to ship to both stores.
Google's cross-platform toolkit. Backed by a big company, huge community, one consistent UI everywhere.
App Store + Google Play: review queues, signing, versioning — the shipper half of mobile. Budget a day for first submission.
A wrong pick is a re-write; a good pick is boring.
One platform matters first, the product lives or dies on camera/GPS/performance, or you want the absolute last percent of polish.
Pay the price once; the other platform comes later.
Being on both stores on day one matters, you're a JS shop (→ React Native) or want one pixel-consistent UI (→ Flutter).
Ship faster, iterate faster — the last 5% can wait.
The JS/Dart → native bridge when the framework can't reach the hardware directly.
APNs/FCM tokens, permission flows, the app pokes the user — a topic with its own paperwork.
Local storage, conflict resolution, going out and back — the hard 10% of real apps.
Signed builds, staged rollouts, in-app purchases, subscriptions — the shipper half of mobile.
A mobile app is just your codebase wearing a device: same state, same build-run-see loop, same ship-it discipline — the only new thing is that the user holds it in their pocket.
You now speak every language in this course — pick one and ship.