React Native lets you build native mobile apps using JavaScript. Integrate it with Strapi to power fast, flexible content experiences across iOS and Android

React Native open-source JavaScript framework that allows developers to build native mobile applications for iOS and Android using the same codebase. React Native brings the best parts of developing with React to native development. It's a best-in-class JavaScript library for building user interfaces.
Visit the React Native documentation for more.
Strapi is the leading open-source headless CMS offering features, like customizable APIs, role-based permissions, multilingual support, etc. It simplifies content management and integrates effortlessly with modern frontend frameworks.
Explore the Strapi documentation for more details.
The out-of-the-box Strapi features allow you to get up and running in no time:
Learn more about Strapi 5 feature.
We are going to start by setting up our Strapi 5 project with the following command:
šļø Note: make sure that you have created a new directory for your project.
You can find the full documentation for Strapi 5 here.
npx create-strapi-app@latest serverYou will be asked to choose if you would like to use Strapi Cloud we will choose to skip for now.
š Welcome to Strapi! Ready to bring your project to life?
Create a free account and get:
30 days of access to the Growth plan, which includes:
⨠Strapi AI: content-type builder, media library and translations
ā
Live Preview
ā
Single Sign-On (SSO) login
ā
Content History
ā
Releases
? Please log in or sign up.
Login/Sign up
⯠SkipAfter that, you will be asked how you would like to set up your project. We will choose the following options:
? Do you want to use the default database (sqlite) ? Yes
? Start with an example structure & data? Yes <-- make sure you say yes
? Start with Typescript? Yes
? Install dependencies with npm? Yes
? Initialize a git repository? YesOnce everything is set up and all the dependencies are installed, you can start your Strapi server with the following command:
cd server
npm run developYou will be greeted with the Admin Create Account screen.

Go ahead and create your first Strapi user. All of this is local so you can use whatever you want.
Once you have created your user, you will be redirected to the Strapi Dashboard screen.

Since we created our app with the example data, you should be able to navigate to your Article collection and see the data that was created for us.

Now, let's make sure that all of the data is published. If not, you can select all items via the checkbox and then click the Publish button.

Once all your articles are published, we will expose our Strapi API for the Articles Collection. This can be done in Settings -> Users & Permissions plugin -> Roles -> Public -> Article.
You should have find and findOne selected. If not, go ahead and select them.

Now, if we make a GET request to http://localhost:1337/api/articles, we should see the following data for our articles.

šļø Note: The article covers (images) are not returned. This is because the REST API by default does not populate any relations, media fields, components, or dynamic zones.. Learn more about REST API: Population & Field Selection.
So, let's get the article covers by using the populate=* parameter: http://localhost:1337/api/articles?populate=*

Nice, now that we have our Strapi 5 server setup, we can start to setup our React Native application.
We will use Expo Dev for this integration. Expo Dev is an open-source development environment provided by Expo that allows developers to build native mobile apps for Android and iOS using JavaScript.
Consider having the following tools to get started:
See expo docs for more setup instructions.
Install React Native using any of the package managers below:
npm:npx create-expo-app@latest react-native-project --template blankyarn:yarn create expo-apppnpm:pnpm create expo-appbun:bun create expoFor this example, I will be using npm. Feel free to use any package manager of your choice.
To start the development server, run the following command:
npx expo startIf successful, this is what you will see in your terminal:

To test and run your app on a device, you can do it in the following ways:
w in your terminal to open the app on your web browser.a in your terminal to start your Android emulator.i in your terminal to start your iOS simulator.See more about setting up your environment.
šļø NOTE: For this integration, we will make use of the Android emulator and the iOS simulator.
After setting up your environment, here is what your application should look like:
Android Emulator
iOS Emulator
Many HTTP clients are available, but on this integration page, we'll use Axios and Fetch.
Install Axios by running any of the commands below:
# npm
npm i axiosOr:
# yarn
yarn add axiosNo installation is needed.
Execute a GET request on the Article collection type in order to fetch all your articles.
Be sure that you activated the find permission for the Article collection type.
šļø NOTE: We want to also fetch covers (images) of articles, so we have to use the populate parameter as seen below.
const response = await fetch("http://localhost:1337/api/articles?populate=*");
const data = await response.json();
console.log(data.data);const response = await fetch("http://localhost:1337/api/articles?populate=*");
const data = await response.json();
console.log(data.data);We will create an app that fetches articles from a Strapi backend and displays them in a grid layout.
Navigate to your React Native entry file ./App.js and carry out the steps below:
import {
View,
Text,
Image,
FlatList,
StyleSheet,
} from "react-native";
import axios from "axios";
import { useEffect, useState } from "react";View, Text, Image, FlatList, and StyleSheet are core React Native components used for structuring the layout, displaying text, images, and styling the app.useEffect and useState are React hooks which manages component state and handles side effects respectively.Create a constant variable, STRAPI_URL, that defines the base URL for the Strapi backend and another variable, articles that will hold the list of articles fetched from the Strapi API.
...
// replace with Strapi Production URL
const STRAPI_URL = "http://localhost:1337";
// State to store articles
const [articles, setArticles] = useState([]);
..Create a function fetchArticles to fetch articles from the Strapi backend and fetch articles once the component is mounted.
...
// fetch articles from Strapi
const fetchArticles = async () => {
try {
// Fetch articles along with their covers
const response = await axios.get(`${STRAPI_URL}/api/articles?populate=*`);
setArticles(response.data.data);
} catch (error) {
console.error("Error fetching articles:", error);
}
};
// Fetch articles on component mount
useEffect(() => {
fetchArticles();
}, []);
...Create a formatDate function formats the publishedAt date of each article into a human-readable string (e.g., 01/14/2025). It should use the toLocaleDateStringmethod with options to display the year, month, and day in anMM/DD/YYYY` format.
...
// Format date
const formatDate = (date) => {
const options = { year: "numeric", month: "2-digit", day: "2-digit" };
return new Date(date).toLocaleDateString("en-US", options);
};
...Render individual articles as cards with an image, title, and formatted publication date using the formatDate utility function.
...
export default function App() {
...
// Render article card
const renderArticle = ({ item }) => (
<View style={styles.card}>
<Image
source={{ uri: `${STRAPI_URL}${item.cover.url}` }}
style={styles.image}
/>
<Text style={styles.title}>{item.title}</Text>
<Text style={styles.published}>
Published: {formatDate(item.publishedAt)}
</Text>
</View>
);
return (
<View style={styles.container}>
<Text style={styles.heading}>React Native and Strapi Integration</Text>
<FlatList
title="Articles"
data={articles}
keyExtractor={(item) => item.id.toString()}
renderItem={renderArticle}
numColumns={2}
contentContainerStyle={styles.container}
/>
</View>
);
}In the code above, we render a list of articles fetched from Strapi, displayed as cards in a two-column grid using FlatList. Each card includes an image, title, and formatted publication date styled using the styles object. The renderArticle function defines how each article card is displayed.
// Path: ./App.js
export default function App() {
// replace with Strapi Production URL
const STRAPI_URL = "http://localhost:1337";
// State to store articles
const [articles, setArticles] = useState([]);
// fetch articles from Strapi
const fetchArticles = async () => {
try {
// Fetch articles along with their covers
const response = await axios.get(`${STRAPI_URL}/api/articles?populate=*`);
setArticles(response.data.data);
} catch (error) {
console.error("Error fetching articles:", error);
}
};
// Format date
const formatDate = (date) => {
const options = { year: "numeric", month: "2-digit", day: "2-digit" };
return new Date(date).toLocaleDateString("en-US", options);
};
// Render article card
const renderArticle = ({ item }) => (
<View style={styles.card}>
<Image
source={{ uri: `${STRAPI_URL}${item.cover.url}` }}
style={styles.image}
/>
<Text style={styles.title}>{item.title}</Text>
<Text style={styles.published}>
Published: {formatDate(item.publishedAt)}
</Text>
</View>
);
// Fetch articles on component mount
useEffect(() => {
fetchArticles();
}, []);
return (
<View style={styles.container}>
<Text style={styles.heading}>React Native and Strapi Integration</Text>
<FlatList
title="Articles"
data={articles}
keyExtractor={(item) => item.id.toString()}
renderItem={renderArticle}
numColumns={2}
contentContainerStyle={styles.container}
/>
</View>
);
}
Here is a break-down of the code above:
fetchArticles function retrieves data from the Strapi API, including article covers, titles, and publication dates, and stores them in the articles state using useState.renderArticle function renders individual articles as cards with an image, title, and formatted publication date using the formatDate utility function.useEffect hook runs fetchArticles on component mount to ensure data is loaded when the app starts.FlatList displays the articles in two columns, with the app styled using a custom StyleSheet for a clean, responsive layout.StyleSheet defines the layout and styling for your app. The container ensures the main screen has proper padding and fills the space, while card styles each item with a rounded, shadowed design. The image, title, and published handle the card's content, ensuring images are proportional, titles are bold, and dates are subtle. The heading styles the main title to be bold, centered, and spaced from the top.Here is how our app should look:

Awesome, great job!
If you are unable to run your app on your device, here are a few solutions:
STRAPI_URL to http://10.0.2.2:1337.See this Expo page for more information.
You can find the complete code for this project in this Github repo.
Get practical by building real-worlds application using the video resources below:
If you have any questions about Strapi 5 or just would like to stop by and say hi, you can join us at Strapi's Discord Open Office Hours Monday through Friday at 12:30 pm - 1:30 pm CST: Strapi Discord Open Office Hours
For more details about the integration above, visit the following documentation: