React vs React Native: Same Ideas, Different Building Blocks

React is the library; React Native uses it to build iOS and Android apps. With React on the web you render HTML elements such as div and button into a browser page. React Native renders its own components, such as View and Text, which become real platform views. Components, props, state and hooks work the same way in both.

Side by side
QuestionReact (web, react-dom)React Native
Runs where?Web browsersiOS and Android apps
Building blocksHTML elements: div, p, img, inputCore components: View, Text, Image, TextInput
StylingCSS files, className, or a style objectstyle prop with JavaScript objects, often from StyleSheet.create
Default flex directionrow (when display: flex)column
Tap or click handleronClickonPress
SharedComponents, JSX, props, state, hooksComponents, JSX, props, state, hooks

Updated

The quickest way to see the difference is to translate a web element into its native counterpart. Search the map below for an HTML tag, a prop or a CSS habit, and each row gives the React Native replacement with a short note on what behaves differently.

Web element to React Native map

Showing 15 of 15 rows

Web elements and their React Native counterparts
React on the webReact NativeWhat changes
<div><View>A container with flexbox layout, style and touch handling. It does not scroll.
<p>, <span>, <h1><Text>All text must be inside Text. Nested Text inherits styles; there are no heading tags.
<img src><Image source={{ uri }}>Network images need an explicit width and height. Local files use require().
<input type="text"><TextInput>onChangeText passes the new string directly instead of an event.
<textarea><TextInput multiline>The multiline prop allows several lines of text.
<input type="password"><TextInput secureTextEntry>Hides the typed text. It does not work together with multiline.
<input type="checkbox"><Switch>A controlled boolean input: update value from onValueChange.
<button><Button> or <Pressable>Button takes a title prop; Pressable wraps any children you want to make tappable.
onClickonPressPressable also offers onPressIn, onPressOut and onLongPress.
<div> with overflow: auto<ScrollView>Renders all of its children at once, so keep it for short content.
<ul> with items.map()<FlatList>Renders long lists efficiently. Needs data and renderItem; keyExtractor sets each key.
<a href="https://...">Linking.openURL(url)Opens the URL with an installed app such as the browser. Wrap it in a Pressable for a tappable link.
className + CSS filestyle={styles.card}Styles are objects, usually defined with StyleSheet.create. Pass an array to combine them; the last wins.
background-colorbackgroundColorStyle names are camelCase, as in React's own style prop on the web.
display: flex (row)flexDirection: "column" (default)Every View is a flex container and stacks children vertically unless told otherwise.

One card, written for both

The component logic is identical: the same props, the same useState call, the same handler. Only the elements and the styling change.

React for the web

HTML elements, a CSS class and onClick. The browser lays out the button after the text.

import { useState } from "react";

export function LikeCard({ title }) {
  const [likes, setLikes] = useState(0);
  return (
    <div className="card">
      <p className="card-title">{title}</p>
      <button onClick={() => setLikes(likes + 1)}>Like ({likes})</button>
    </div>
  );
}

React Native for iOS and Android

View, Text and Pressable from react-native, styles from StyleSheet.create, and onPress in place of onClick.

import { useState } from "react";
import { Pressable, StyleSheet, Text, View } from "react-native";

export function LikeCard({ title }) {
  const [likes, setLikes] = useState(0);
  return (
    <View style={styles.card}>
      <Text style={styles.title}>{title}</Text>
      <Pressable onPress={() => setLikes(likes + 1)} style={styles.button}>
        <Text>Like ({likes})</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  card: { padding: 16, borderRadius: 12, backgroundColor: "#fff" },
  title: { fontSize: 18, fontWeight: "600", marginBottom: 8 },
  button: { alignSelf: "flex-start", paddingVertical: 8, paddingHorizontal: 12 },
});

Lists: map() on the web, FlatList on a phone

The same list in React Native

FlatList only renders what is near the screen, which keeps long lists smooth. keyExtractor plays the role of the key prop.

import { FlatList, Text } from "react-native";

const products = [
  { id: "p1", name: "Desk lamp" },
  { id: "p2", name: "Notebook" },
];

export function ProductList() {
  return (
    <FlatList
      data={products}
      keyExtractor={(item) => item.id}
      renderItem={({ item }) => <Text>{item.name}</Text>}
    />
  );
}

What is shared, and what is not

Both use the react package. Function components, JSX, props, state, effects, context and custom hooks are identical, and a hook such as useState behaves the same on a phone as in a browser.

What differs is the renderer. On the web, react-dom turns components into HTML elements. In React Native, components such as View and Text are turned into platform views, so everything that depends on the DOM, from document.querySelector to CSS selectors, is not available.

Text and layout rules that catch web developers

In React Native every string must sit inside a Text component; a bare string under a View raises an error. Style inheritance is also limited: nested Text inherits from its parent Text, but a View passes nothing down to its children.

Flexbox is the layout system, but flexDirection defaults to column, alignContent to flex-start and flexShrink to 0, and flex accepts a single number only. Layouts copied from web CSS often need flexDirection: "row" added.

When to choose each

Choose React for anything people open in a browser: marketing sites, dashboards, web apps and content that must be found by search engines. Choose React Native when you need an app in the iOS and Android stores, with access to device features and native navigation.

Many teams use both: a React web app plus a React Native app sharing types and API code. If you are also weighing Next.js on the web side, the Next.js vs React guide on this site covers that choice.

How it works

  1. Type an HTML element, prop or CSS idea into the search box, for example img, onClick or class.
  2. Read the React Native column for the replacement component, prop or API.
  3. Check the note for the behaviour that changes, such as required image sizes or text that must sit inside Text.
  4. Use the code examples further down to see the same small card written for both platforms.

Tips

Frequently asked questions

Is React Native the same as React?

No. React is the component library; React Native is a framework that uses React to drive native mobile views. You write components the same way, but you render View, Text and other native components instead of HTML, and there is no browser DOM.

Can I use HTML and CSS in React Native?

Not directly. There are no div or span elements and no CSS files. Styles are JavaScript objects with camelCase names that mostly mirror CSS, and layout uses flexbox with a few different defaults.

Should I learn React or React Native first?

React first, in most cases. React Native's own documentation teaches React's components, JSX, props and state as the foundation, and practising them on the web gives you faster feedback.

Can a React web app and a React Native app share code?

The logic can be shared: types, API clients, validation and hooks that do not touch the DOM. Screens and components usually are not, because they render different primitives.

Does React Native produce a real native app?

Yes. React Native's documentation explains that at runtime it creates the matching Android and iOS views for its components, so a View becomes a native view rather than a web page in a wrapper.

Related: Next.js vs React, React with TypeScript, React Native text input, Forms in React Native, TypeScript data types.

Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.

More in Guides

We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.

Product

Who It's For

Features

Resources

Company

View Sitemap