React Native Prototype: A Small, Verifiable Start
Mobile prototypes only matter if they run on an actual simulator or device. A repo that “looks right” but won’t boot is just text.
This post is a small React Native prototype you can verify. The goal is not to build an app. The goal is to create a fresh project, change one file, and prove you can see your change on screen. Once you can do that, everything else becomes normal incremental work instead of guesswork.
What you are building
You are building the smallest possible React Native app that prints a single line of text in a safe area. That sounds boring, but it is the right baseline because it proves the entire chain works: Node can run the CLI, the native project exists, the bundler can serve JavaScript, the native shell can load it, and the screen can render.
React Native is just React code running inside a native shell. The “native” part is real. iOS builds use Xcode. Android builds use Gradle and the Android toolchain. The JavaScript is still yours, but the last mile is a real native app.
What you need and why you need it
React Native is one of those setups where missing one piece can waste a whole night. So here is what matters and why.
You need Node because the React Native CLI is a Node tool. You need Xcode if you plan to run iOS because iOS builds are Xcode projects under the hood. You need Android Studio if you plan to run Android because it provides the SDK, emulator, and build tools that Gradle expects.
If you only want one platform right now, pick one. iOS on macOS is usually the smoother path because Xcode + Simulator are tightly integrated. Android is totally fine too, but your setup surface area is bigger because the SDK, emulator image, and Java requirements have more moving parts.
Quick environment sanity checks
Before you scaffold anything, do these checks. They are not “optional best practices.” They are just the fastest way to confirm you are not walking into a setup trap.
First, confirm Node exists and is not ancient.
node -vnpm -v
If you do not see versions printed, stop and fix Node first. A lot of React Native errors are just “you are missing Node” wearing a mask.
Second, if you are doing iOS, confirm Xcode command line tools are installed and the license is accepted. This is one of the most common iOS failure modes.
xcode-select -psudo xcodebuild -license accept
Third, if you are doing Android, confirm you have Android Studio installed and that you can open the SDK Manager and install at least one emulator image. If you do not have an emulator that can boot, run-android has nothing to target.
Start to finish
Step 1: Create the project
This is the scaffold step. It creates the repo, the native shells, and the default starter app.
npx react-native@latest init NativeLabcd NativeLab
What that command actually does matters. It generates a project folder, installs the JavaScript dependencies, and creates the native folders (ios/ and android/) that Xcode and Gradle will build. If those folders do not exist, you do not have a real React Native project.
Verify it worked:
Open the folder and confirm you see ios/ and android/.
If it fails, do not try to “fix it by guessing.” Read the exact CLI output. Most failures are missing prerequisites or permissions.
Step 2: Edit the one file that proves everything
React Native projects can get noisy fast. The point here is to keep the first change dead simple so you can see the feedback loop.
Open App.tsx and replace it with this:
import React from "react";import { SafeAreaView, Text } from "react-native";export default function App() {return (<SafeAreaView style={{ padding: 24 }}><Text>NativeLab is running.</Text></SafeAreaView>);}
Here is what that code is doing in plain terms. SafeAreaView prevents your content from sitting under the notch or the status bar on iOS. The inline padding: 24 makes it obvious the layout is yours, not the default template. The Text component is the simplest visible output you can render on every platform.
Verify it worked:
The file should save cleanly with no TypeScript errors. If your editor highlights the imports as missing, it usually means your dependency install did not complete.
Step 3: Run it on iOS
If you are on macOS and you installed Xcode, this is the most direct proof.
npx react-native run-ios
What is happening during this step is important. The CLI kicks off a native build in the background, launches Simulator, starts Metro (the JavaScript bundler), then the app connects to Metro to load your JavaScript bundle.
Verify it worked:
You should see the Simulator open and the text NativeLab is running. on screen.
If it fails, the most common causes are: Xcode not installed, Xcode license not accepted, or missing command line tools.
Step 4: Run it on Android
Android requires an emulator or device connected through ADB. Start the emulator first, then run:
npx react-native run-android
Android failures are often not “React Native problems.” They are toolchain problems. Wrong SDK path, no emulator running, Gradle failing, Java version mismatch. The good news is that once you get one project to run, the next ones are much easier because the machine is configured.
Verify it worked:
The emulator should open the app and show the same text.
What “running” actually means
A lot of beginners think “it ran” means “the command finished.” In React Native, “it ran” means you can change JavaScript and reliably see the change on screen. That is the real prototype loop.
So after you see the screen once, change the text to something else, save, and confirm the app updates. That is your proof that Metro is serving your bundle correctly and the app is connected.
Common failures that look like React Native but are not
React Native errors are usually symptoms, not causes. Here are the ones that show up the most.
Metro is not running
If the app launches but you see a blank screen or bundle loading issues, Metro might not be running.
Run:
npx react-native start
Keep that terminal open, then in a second terminal run run-ios or run-android again.
iOS build fails immediately
If you see build failures that look like Xcode toolchain errors, it usually means Xcode is missing or not configured.
The two fastest checks:
xcode-select -psudo xcodebuild -license accept
Then retry the run command.
Android says it cannot find a device
That is almost always “your emulator is not running” or “ADB cannot see it.” Start an emulator from Android Studio Device Manager, then run:
adb devices
If nothing shows up, the React Native CLI cannot target anything.
Gradle errors that feel random
Gradle errors are loud and annoying, but the fix usually lives in the first real error line, not the bottom. Scroll up until you find the first failure that mentions a missing SDK, missing Java, or an incompatible version.
What you should do next (still small)
Once your baseline runs, keep the next move small. Add one button. Add one press handler. Change the layout slightly. The point is to keep the feedback loop alive while you learn the shape of React Native.
If you want a clean next step that still stays verifiable, add a button that toggles text so you confirm state updates in the app.
Replace App.tsx with this:
import React from "react";import { SafeAreaView, Text, Pressable, View } from "react-native";export default function App() {const [on, setOn] = React.useState(false);return (<SafeAreaView style={{ padding: 24 }}><View style={{ gap: 12 }}><Text style={{ fontSize: 18 }}>{on ? "State is ON" : "State is OFF"}</Text><PressableonPress={() => setOn((v) => !v)}style={{paddingVertical: 12,paddingHorizontal: 16,borderRadius: 10,borderWidth: 1,}}><Text>Toggle</Text></Pressable></View></SafeAreaView>);}
This is still minimal, but it proves something more than static rendering. It proves state changes render correctly, touch input works, and your development loop is stable.
Related links
The React Native docs have two different setup paths (Expo and React Native CLI). This post is the React Native CLI path because it forces you to prove the native toolchain works.
https://reactnative.dev/docs/environment-setup
Final check
If you can do these three things, you have a real starting point: create the project, run it, and change JavaScript and see the update on screen. Everything else builds on top of that.