Your First App
In this article, we will break down the default App.js, meet the core components that replace HTML in React Native, and then use them to build a profile card screen step by step.
Anatomy of App.js
Open the App.js that create-expo-app generated for you:
import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, View } from "react-native";
export default function App() {
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});
Let's walk through it:
- Imports — components come from the
react-nativepackage, not from the browser. There is nodiv,span, orimghere. - The App component — a plain function component, exactly like in React on the web. It returns JSX describing the screen.
- StyleSheet — styles live in JavaScript objects instead of CSS files.
StyleSheet.createvalidates them and lets you reference them by name.
If you know React, you already know 90 percent of this. The remaining 10 percent is learning which components to use and how styling works.
Core components
React Native gives you native building blocks instead of HTML tags. The four you will use constantly:
| React Native | Closest web equivalent | Purpose |
|---|---|---|
View | div | Container and layout box |
Text | p or span | Displays text |
Image | img | Displays local or remote images |
ScrollView | a scrollable div | Makes content scrollable |
A few rules that surprise web developers:
Every piece of text must be wrapped in a Text component. Putting a raw string directly inside a View throws an error. There is no inheritance of font styles from a View either — text styling belongs on Text components.
Here they all are together:
import { ScrollView, Image, StyleSheet, Text, View } from "react-native";
export default function App() {
return (
<ScrollView contentContainerStyle={styles.container}>
<Text style={styles.title}>Core Components</Text>
<View style={styles.box}>
<Text>I am text inside a View.</Text>
</View>
<Image
style={styles.picture}
source={{ uri: "https://picsum.photos/200" }}
/>
</ScrollView>
);
}
const styles = StyleSheet.create({
container: { padding: 24, alignItems: "center" },
title: { fontSize: 24, fontWeight: "bold", marginBottom: 16 },
box: { backgroundColor: "#e0e7ff", padding: 16, borderRadius: 8 },
picture: { width: 200, height: 200, marginTop: 16, borderRadius: 8 },
});
Remote images need an object with a uri key and an explicit width and height, because the layout engine cannot know the size of a network image ahead of time. Local images use require("./assets/photo.png") and size themselves automatically.
Styling with StyleSheet and flexbox
Every layout in React Native is flexbox. There is no grid, no floats, and no CSS files. The most important defaults to remember:
flexDirectiondefaults tocolumn(the web defaults torow), so children stack vertically.- All sizes are unitless numbers representing density independent pixels — write
16, not"16px". - Property names are camelCase:
backgroundColor,justifyContent,alignItems. flex: 1makes a component expand to fill the available space in its parent.
The two properties you will reach for most:
justifyContent— positions children along the main axis (vertical by default).alignItems— positions children along the cross axis (horizontal by default).
Building a profile card
Time to put it all together. We will build a profile card screen in three steps.
Step 1 - lay out the structure
Start with the skeleton: a full screen container with a card in the middle.
import { StyleSheet, Text, View } from "react-native";
export default function App() {
return (
<View style={styles.screen}>
<View style={styles.card}>
<Text>Card goes here</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
screen: {
flex: 1,
backgroundColor: "#f1f5f9",
justifyContent: "center",
alignItems: "center",
},
card: {
width: "85%",
backgroundColor: "#ffffff",
borderRadius: 16,
padding: 24,
alignItems: "center",
},
});
The screen style uses flex: 1 to take the full screen, then centers the card with justifyContent and alignItems.
Step 2 - add the avatar and text
Replace the placeholder with an image, a name, a role, and a short bio:
<View style={styles.card}>
<Image
style={styles.avatar}
source={{ uri: "https://i.pravatar.cc/300" }}
/>
<Text style={styles.name}>Sara Malik</Text>
<Text style={styles.role}>Mobile Engineer</Text>
<Text style={styles.bio}>
Building smooth mobile experiences with React Native. Coffee first,
commits second.
</Text>
</View>
Add the matching styles to the StyleSheet.create call:
avatar: {
width: 96,
height: 96,
borderRadius: 48,
marginBottom: 16,
},
name: { fontSize: 22, fontWeight: "bold", color: "#0f172a" },
role: { fontSize: 14, color: "#64748b", marginBottom: 12 },
bio: { fontSize: 14, color: "#334155", textAlign: "center", lineHeight: 20 },
Setting borderRadius to half of the width and height turns the square image into a circle.
Step 3 - add a stats row
A horizontal row is just a View with flexDirection set to row. Add this below the bio:
<View style={styles.statsRow}>
<View style={styles.stat}>
<Text style={styles.statValue}>128</Text>
<Text style={styles.statLabel}>Posts</Text>
</View>
<View style={styles.stat}>
<Text style={styles.statValue}>4.2k</Text>
<Text style={styles.statLabel}>Followers</Text>
</View>
<View style={styles.stat}>
<Text style={styles.statValue}>310</Text>
<Text style={styles.statLabel}>Following</Text>
</View>
</View>
And its styles:
statsRow: {
flexDirection: "row",
justifyContent: "space-around",
alignSelf: "stretch",
marginTop: 20,
paddingTop: 16,
borderTopWidth: 1,
borderTopColor: "#e2e8f0",
},
stat: { alignItems: "center" },
statValue: { fontSize: 18, fontWeight: "bold", color: "#0f172a" },
statLabel: { fontSize: 12, color: "#64748b", marginTop: 2 },
Save the file and check your phone — a complete profile card, built entirely from View, Text, and Image with flexbox.
Conclusion
You learned the anatomy of App.js, the core components that replace HTML, and how StyleSheet and flexbox handle all layout in React Native. In the next article, we make the screen interactive with text input, buttons, lists, and state.