The Development Environment — Your First Screen With Expo
The fastest way into React Native is Expo. We create a project, get a first screen running on a real device in your hand, and look at what separates Expo from the bare workflow — and why Expo is the recommended starting point today.
Last time we pinned down what React Native is: the same React with the renderer swapped out for a native one. Now it’s time to actually move our hands. Today’s goal is a single thing — getting an app you made onto the screen of the phone in your pocket.
On the web this step was featherweight. Open an HTML file in a browser and you’re done. Mobile is a different situation. An app runs on an OS rather than a browser, and that OS lives on a different device, not on your computer. So “how do I get the thing I made to run over there?” is a problem from the very first minute. The tool that smooths this over best is Expo.
What Expo Handles for You
There are broadly two paths into a React Native project.
One is the bare workflow. You take hold of an iOS project and an Android project directly. Which means installing Xcode on a Mac, plus Android Studio and a JDK, and setting up simulators and emulators. When a native build fails, you end up wrestling with error messages from Gradle or CocoaPods — tools that have nothing to do with what you set out to learn. Plenty of people quit right here, before ever seeing a first screen.
The other is Expo. Expo manages that native layer on your behalf. You write JavaScript; Expo supplies the native shell needed to run it, ready-made. You can start developing without Xcode or Android Studio, build for Android without owning an iPhone, and make an app without owning a Mac. Today the official React Native documentation itself points newcomers to Expo first.
“But what if I need to touch native code deeply later?” is the natural worry that follows. There used to be a hard decision at that point — ejecting out of Expo entirely. Not anymore. When you need it, the path to opening up the native code and working alongside it is there. Starting with Expo doesn’t mortgage your future. So begin with it, without agonizing over the choice.
Creating the Project
If Node.js is installed, you’re ready. One line in a terminal creates the project.
npx create-expo-app@latest my-app
cd my-app
npx fetches and runs a package on the spot instead of installing it globally — the same feeling as create-vite or create-next-app on the web.
Open the folder and familiar things look back at you. There’s a package.json, there’s node_modules, there are JavaScript files. This is where last post’s claim — “the React ecosystem carries over” — becomes concrete. The conspicuous difference is the app/ folder: the file structure inside it becomes the screen structure of your app. It’s similar to file-based routing on the web, and we’ll take navigation on properly in post 6.
Onto a Real Device
Now start the dev server.
npx expo start
A QR code appears in the terminal. This is where things depart from the web entirely. Install the Expo Go app on your phone and scan that QR code. A moment later, the app you just made is running in your hand. No Xcode, no emulator, no cable.
Knowing why this works will keep you calm when something breaks later. Expo Go is an app whose native shell is already built. The dev server bundles up only the JavaScript we wrote and ships it over; Expo Go receives it and runs it inside itself. In other words, we didn’t build and install an app — we sent our JavaScript into a shell that was already installed. That’s also why your computer and phone must be on the same Wi-Fi. If the scan doesn’t connect, nine times out of ten the network is split.
Prefer a simulator or emulator? Press i (iOS) or a (Android) in the terminal — that path does require Xcode or Android Studio. Press w and it opens in a browser, too. But don’t take comfort from the web preview looking fine. What we’re building is a native screen, and its true face has to be checked on a device.
Editing the First Screen
Open app/index.tsx (or .jsx), clear it, and try this.
import { View, Text } from 'react-native';
export default function Home() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Hello, React Native.</Text>
</View>
);
}
Save, and the phone screen changes. The Fast Refresh you know from the web works here exactly the same: edit, save, see it immediately, with component state preserved wherever possible. This short round trip is a large part of what makes developing in React Native enjoyable.
Everything the last post promised is already sitting in these few lines. We wrote View, not div. We wrapped the words in Text rather than leaving them bare. The style went in as a JavaScript object, not a CSS file, and flex: 1 means “take all the remaining space.” Each of those is the subject of post 3 and post 4. For now, letting your eye get used to the shape is enough.
Where People Get Stuck
Scanned the QR, nothing happens. Usually the network. Check that computer and phone are on the same Wi-Fi. Shared office or café networks sometimes block device-to-device traffic; npx expo start --tunnel routes around that.
Saved, but the screen won’t change. Press r in the terminal to reload. If that doesn’t do it, restarting the dev server is the faster path.
Works on web, broken on the device. That’s normal. The web preview is a convenience, and the two environments render differently. What you see on the device is the truth.
Wrapping Up
What we did today is simple but load-bearing. We built the round trip where editing JavaScript shows up instantly on the device in your hand. Every post from here runs on top of that loop — which means whatever you learn, you can see it on screen right away.
Next time we take on the View and Text that slipped in above. In a world with no div and no span, what exactly is a screen made of — and why must every piece of text be wrapped in Text?