<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ John Caleb - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ John Caleb - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 23 May 2026 22:19:56 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/THEJOHNCALEB/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Store Data Locally in React Native Expo ]]>
                </title>
                <description>
                    <![CDATA[ React Native has grown in popularity as a mobile application development tool because of its ability to create cross-platform applications using familiar JavaScript and React principles.  When building mobile applications, one common requirement is t... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-store-data-locally-in-react-native-expo/</link>
                <guid isPermaLink="false">66b9ee747bae781916c2d6dd</guid>
                
                    <category>
                        <![CDATA[ localstorage ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React Native ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ John Caleb ]]>
                </dc:creator>
                <pubDate>Mon, 13 May 2024 11:42:45 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/05/local-storage-in--react-native-expo--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>React Native has grown in popularity as a mobile application development tool because of its ability to create cross-platform applications using familiar JavaScript and React principles. </p>
<p>When building mobile applications, one common requirement is the ability to save data locally on the device. This is when local storage comes into play. <a target="_blank" href="https://docs.expo.dev/versions/latest/sdk/async-storage/">Async Storage</a>, provided by React Native Expo, is a simple but powerful solution for saving data locally within your React Native Expo apps.</p>
<p>In this tutorial, we'll discuss the fundamentals of local storage, introduce Async Storage, and demonstrate how to properly integrate it into React Native Expo projects.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></li>
<li><a class="post-section-overview" href="#heading-what-is-local-storage">What is Local Storage?</a></li>
<li><a class="post-section-overview" href="#heading-what-is-async-storage">What is Async Storage?</a></li>
<li><a class="post-section-overview" href="#heading-how-to-get-started-with-async-storage">How to Get Started with Async Storage</a></li>
<li><a class="post-section-overview" href="#heading-understanding-async-storage-methods">Understanding Async Storage Methods</a></li>
<li><a class="post-section-overview" href="#heading-advanced-usage-and-best-practices">Advanced Usage and Best Practices</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li>Familiarity with React Native and JavaScript.</li>
<li>Node.js and npm (or yarn) installed.</li>
</ul>
<h2 id="heading-what-is-local-storage">What is Local Storage?</h2>
<p>Local storage is an essential component of mobile app development, allowing developers to store data on the user's device. Unlike other storage choices such as databases, Local Storage uses a straightforward key-value pair storage technique.</p>
<p>Developers can use it to save small quantities of data that remain stored even when they close the program or restart the device. This makes it excellent for storing user preferences, authentication tokens, and other important information.</p>
<p>Local storage is essential for boosting app speed because it eliminates the need to retrieve data from faraway servers regularly.</p>
<h2 id="heading-what-is-async-storage">What is Async Storage?</h2>
<p>Async Storage is a key-value storage system supplied by React Native Expo that allows you to manage local storage in mobile apps. It provides a simple key-value storage system that enables developers to store and retrieve data asynchronously. </p>
<p>Unlike synchronous storage methods, Async Storage allows you to save and retrieve data without interrupting the main thread, resulting in a more seamless user experience.</p>
<h2 id="heading-how-to-get-started-with-async-storage">How to Get Started with Async Storage</h2>
<p>To use Async Storage in your React Native Expo project, ensure that Expo is installed. If you haven't already set up a React Native Expo project, you can do so by installing Expo CLI:</p>
<pre><code class="lang-bash">$ npm install -g expo-cli
</code></pre>
<p>Create a new Expo project:</p>
<pre><code class="lang-bash">$ expo init MyProject
$ <span class="hljs-built_in">cd</span> MyProject
</code></pre>
<p>To add Async Storage to your project, run the following command:</p>
<pre><code class="lang-js">$ expo install @react-native-<span class="hljs-keyword">async</span>-storage/<span class="hljs-keyword">async</span>-storage
</code></pre>
<p>The <code>@react-native-async-storage/async-storage</code> is a community-maintained version of AsyncStorage. Once installed, you can then setup a file to handle the AsyncStorage methods such as <code>setItem()</code>, <code>updateItem()</code>, <code>deleteItem()</code>, and others. This file would be imported whenever you want to make a call to the local storage. </p>
<p>In this example, we'll create a folder named <code>utils</code> in the root path of our project and then create the <code>AsyncStorage.js</code> file to handle these methods:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/-4611C08C-3557-460A-A7CC-BFD754BD13F7-.png.jpg" alt="Async Storage File Structure " width="600" height="400" loading="lazy">
<em>Async Storage File Structure</em></p>
<p>Within the <code>AsyncStorage.js</code> file, you can define the AsyncStorage methods like this:</p>
<pre><code class="lang-js"><span class="hljs-comment">// utils/AsyncStorage.js</span>

<span class="hljs-keyword">import</span> AsyncStorage <span class="hljs-keyword">from</span> <span class="hljs-string">'@react-native-async-storage/async-storage'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> setItem = <span class="hljs-keyword">async</span> (key, value) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">await</span> AsyncStorage.setItem(key, <span class="hljs-built_in">JSON</span>.stringify(value));
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error setting item:'</span>, error);
  }
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getItem = <span class="hljs-keyword">async</span> (key) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> value = <span class="hljs-keyword">await</span> AsyncStorage.getItem(key);
    <span class="hljs-keyword">return</span> value != <span class="hljs-literal">null</span> ? <span class="hljs-built_in">JSON</span>.parse(value) : <span class="hljs-literal">null</span>;
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error getting item:'</span>, error);
    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
  }
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> removeItem = <span class="hljs-keyword">async</span> (key) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">await</span> AsyncStorage.removeItem(key);
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error removing item:'</span>, error);
  }
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> mergeItem = <span class="hljs-keyword">async</span> (key, value) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">await</span> AsyncStorage.mergeItem(key, <span class="hljs-built_in">JSON</span>.stringify(value));
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error merging item:'</span>, error);
  }
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> clear = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">await</span> AsyncStorage.clear();
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error clearing AsyncStorage:'</span>, error);
  }
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getAllKeys = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> AsyncStorage.getAllKeys();
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error getting all keys:'</span>, error);
    <span class="hljs-keyword">return</span> [];
  }
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getAllItems = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> keys = <span class="hljs-keyword">await</span> AsyncStorage.getAllKeys();
    <span class="hljs-keyword">const</span> items = <span class="hljs-keyword">await</span> AsyncStorage.multiGet(keys);
    <span class="hljs-keyword">return</span> items.reduce(<span class="hljs-function">(<span class="hljs-params">accumulator, [key, value]</span>) =&gt;</span> {
      accumulator[key] = <span class="hljs-built_in">JSON</span>.parse(value);
      <span class="hljs-keyword">return</span> accumulator;
    }, {});
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error getting all items:'</span>, error);
    <span class="hljs-keyword">return</span> {};
  }
};
</code></pre>
<p>Moving forward, In the next section, we'll explain and break down the meaning of these AsyncStorage functions in the AsyncStorage.js file.</p>
<h2 id="heading-understanding-async-storage-methods">Understanding Async Storage Methods</h2>
<p>By separating AsyncStorage functions into their own file, you can conveniently manage and reuse them throughout your React Native Expo project. This modular approach improves code maintenance and readability.</p>
<p>In the previous section, we created the <code>AsyncStorage.js</code> file and added several functions. </p>
<p>In the following sections, we'll talk about these methods and how to use them effectively.</p>
<h3 id="heading-setitem"><code>setItem()</code></h3>
<p>This method is essential for storing data locally on the device. It allows developers to store key-value pairs in AsyncStorage, where the key serves as a unique identifier and the value represents the data to be stored.</p>
<pre><code class="lang-js"><span class="hljs-keyword">await</span> AsyncStorage.setItem(<span class="hljs-string">'username'</span>, <span class="hljs-string">'freeCodeCamp'</span>);
</code></pre>
<h3 id="heading-getitem"><code>getItem()</code></h3>
<p>The <code>getItem()</code> method returns the value associated with a given key from local storage. It sends a parameter/key, which is the unique identification of the data being requested. And it returns the value associated with the supplied key, or null if no value is discovered for the given key.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> username = <span class="hljs-keyword">await</span> AsyncStorage.getItem(<span class="hljs-string">'username'</span>);
</code></pre>
<p>In this scenario, the value for the key <code>username</code> is fetched from local storage. This obtained value, <code>freeCodeCamp</code>, is then placed in the variable username, making it available for further use across the application.</p>
<h3 id="heading-removeitem"><code>removeItem()</code></h3>
<p>This function deletes the object with the supplied key from local storage. It's useful when you want to remove a specific piece of data that's no longer required.</p>
<pre><code class="lang-js"><span class="hljs-keyword">await</span> AsyncStorage.removeItem(<span class="hljs-string">'username'</span>);
</code></pre>
<p>In this example, the object identified by the key <code>username</code> is removed from local storage.</p>
<h3 id="heading-mergeitem"><code>mergeItem()</code></h3>
<p>The <code>mergeItem()</code> method combines the value of an existing key with the value supplied as input. If the key do not exists, it works similarly to <code>setItem()</code>, creating a new key-value pair.</p>
<pre><code class="lang-js"><span class="hljs-keyword">await</span> AsyncStorage.mergeItem(<span class="hljs-string">'user'</span>, <span class="hljs-built_in">JSON</span>.stringify({ <span class="hljs-attr">name</span>: <span class="hljs-string">'John'</span> }));
</code></pre>
<h3 id="heading-clear"><code>clear()</code></h3>
<p>The <code>clear()</code> method deletes all items from local storage. It's useful when you wish to delete all local data, such as when you log out of a user or reset the application state.</p>
<pre><code class="lang-js"><span class="hljs-keyword">await</span> AsyncStorage.clear();
</code></pre>
<h3 id="heading-getallkeys"><code>getAllKeys()</code></h3>
<p>The <code>getAllKeys()</code> function returns all keys kept in local storage. It's useful when you need to loop through all keys or conduct operations based on the keys in local storage.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> keys = <span class="hljs-keyword">await</span> AsyncStorage.getAllKeys();
</code></pre>
<h3 id="heading-multiget"><code>multiGet()</code></h3>
<p>The <code>multiGet()</code> function obtains several key-value pairs from local storage using an array of keys provided.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> AsyncStorage.multiGet([<span class="hljs-string">'username'</span>, <span class="hljs-string">'email'</span>]);
</code></pre>
<p>In this example, the values for the keys <code>username</code> and <code>email</code> are fetched from local storage.</p>
<h2 id="heading-advanced-usage-and-best-practices">Advanced Usage and Best Practices</h2>
<p>While AsyncStorage provides a straightforward interface for local storage, there are several best practices to consider:</p>
<ol>
<li><strong>Data Serialization</strong>: When storing complex data types such as objects or arrays, remember to serialize them into a string format using <code>JSON.stringify()</code> before storing and deserialize them using <code>JSON.parse()</code> when retrieving.</li>
<li><strong>Error Handling</strong>: Implement robust error handling to gracefully handle any failures that may occur during Async Storage operations.</li>
<li><strong>Security Considerations</strong>: Be mindful of the sensitivity of the data being stored locally and implement appropriate security measures such as encryption for sensitive information.</li>
</ol>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In conclusion, using local storage into your React Native Expo projects is essential for developing robust and responsive mobile applications. Async Storage simplifies the process of storing and retrieving data on the device, providing a consistent user experience and enabling offline functionalities. </p>
<p>By following the steps provided in this article, you can utilize Async Storage to improve your apps local storage functionality.</p>
<p>Remember, if you have any questions or just want to say hi, feel free to reach me on <a target="_blank" href="https://twitter.com/thejohncaleb">X(Twitter)</a> or my <a target="_blank" href="https://thejohncaleb.netlify.app/contact">website</a>. :)  </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Add Tailwind CSS to Your React Native Expo App ]]>
                </title>
                <description>
                    <![CDATA[ Tailwind CSS has been quite popular in the web development world due to its utility-first approach and seamless integration.  However, when developing mobile apps with React Native, integrating Tailwind CSS may be challenging. But guess what? Not any... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/tailwindcss-in-react-native-expo/</link>
                <guid isPermaLink="false">66b9ee776a5986e4892f960b</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CSS3 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React Native ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tailwind ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ John Caleb ]]>
                </dc:creator>
                <pubDate>Tue, 27 Feb 2024 09:22:11 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/02/FREECODE-CAMP-DEFAULT-1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Tailwind CSS has been quite popular in the web development world due to its utility-first approach and seamless integration. </p>
<p>However, when developing mobile apps with React Native, integrating Tailwind CSS may be challenging. But guess what? Not anymore. With the development of tools such as <a target="_blank" href="https://www.nativewind.dev/">NativeWind</a>, React Native developers can leverage Tailwind CSS power to design stunning and responsive mobile UIs easily.</p>
<p>In this tutorial, you'll learn the process of integrating Tailwind CSS to your React Native <a target="_blank" href="https://expo.io/">Expo</a> app using NativeWind. We'll also build a simple login screen with NativeWind.</p>
<h2 id="heading-table-of-contents">Table of Contents:</h2>
<ul>
<li><a class="post-section-overview" href="#heading-whats-nativewind">What's NativeWind?</a></li>
<li><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></li>
<li><a class="post-section-overview" href="#heading-getting-started">Getting Started</a> </li>
<li><a class="post-section-overview" href="#heading-how-to-create-a-new-expo-app">How to Create A New Expo App</a></li>
<li><a class="post-section-overview" href="#heading-how-to-install-nativewind">How to Install NativeWind</a></li>
<li><a class="post-section-overview" href="#heading-how-to-set-up-tailwind-css">How to Set Up Tailwind CSS</a></li>
<li><a class="post-section-overview" href="#heading-how-to-configure-nativewind-with-babel">How to Configure NativeWind With Babel</a></li>
<li><a class="post-section-overview" href="#heading-how-to-style-with-nativewind">How to Style with NativeWind</a></li>
<li><a class="post-section-overview" href="#heading-how-to-build-a-simple-login-screen">How to Build A Simple Login Screen</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h2 id="heading-whats-nativewind">What's NativeWind?</h2>
<p>NativeWind acts as a bridge between Tailwind CSS and React Native Expo, allowing developers to take advantage of Tailwind's utility-first approach in their mobile app development workflow. </p>
<p>NativeWind provides various benefits to developers, some of these benefits include:</p>
<ul>
<li><strong>Familiar Syntax</strong>: Developers that are familiar with Tailwind CSS can easily migrate to using NativeWind in their React Native projects, easing the learning curve.</li>
<li><strong>Consistent Styling:</strong> NativeWind ensures consistent styling across platforms by offering a single collection of components and services.</li>
<li><strong>Flexibility</strong>: NativeWind allows developers to easily adapt and extend styles to meet the app's design specifications.</li>
</ul>
<p>Overall, It provides a collection of components and tools that are very similar to Tailwind CSS, allowing developers to create shorter, more concise code while preserving flexibility and consistency across platforms.</p>
<blockquote>
<p>Tailwind makes writing code feel like I’m using a design tool - Didier Catz</p>
</blockquote>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li>Basic Understanding of React Native Expo and Tailwind CSS.</li>
<li>Node.js and npm (or yarn) installed.</li>
<li>Willingness to learn :)</li>
</ul>
<h2 id="heading-getting-started">Getting Started</h2>
<p>Before you dive into integrating Tailwind CSS into your React Native Expo app, you'll need to ensure that you have the necessary tools set up.</p>
<p>If you haven't already installed Expo and <a target="_blank" href="https://www.npmjs.com/package/expo-cli">expo-cli</a> globally, you can do so using npm or yarn:</p>
<pre><code class="lang-bash">npm install -g expo-cli
</code></pre>
<p>or </p>
<pre><code class="lang-bash">yarn global add expo-cli
</code></pre>
<h2 id="heading-how-to-create-a-new-expo-app">How to Create A New Expo App</h2>
<p>With expo-cli installed, you can now create a new React Native Expo project. </p>
<p>Navigate to the directory where you wish to create your project and open the terminal. You can do this by pressing <em>CTRL + `</em> on Visual Studio Code. Then execute this command in the terminal:</p>
<pre><code class="lang-bash">npx create-expo-app simpleproject
</code></pre>
<p>This command creates an expo project in your directory.</p>
<h2 id="heading-how-to-install-nativewind">How to Install NativeWind</h2>
<p>After creating your expo project, you can install NativeWind and its dependencies by running the following commands in your project's directory:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> simpleproject
npm i nativewind
npm i --dev tailwindcss@3.3.2
</code></pre>
<p>or</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> simpleproject
yarn add nativewind
yarn add --dev tailwindcss@3.3.2
</code></pre>
<p>Next, you'll need to create a <code>tailwind.config.js</code> file. To do this, run this command in your terminal:</p>
<pre><code class="lang-bash">npx tailwindcss init
</code></pre>
<p>This would result in a <code>tailwind.config.js</code> file in your project's root directory. </p>
<h2 id="heading-how-to-set-up-tailwind-css">How to Set Up Tailwind CSS</h2>
<p>To set up Tailwind CSS in your project, navigate to your <code>tailwind.config.js</code> file, and under <code>content</code>, enter the paths to your components. Your <code>tailwind.config.js</code> file would then look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">/** <span class="hljs-doctag">@type <span class="hljs-type">{import('tailwindcss').Config}</span> </span>*/</span>
<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">content</span>: [
    <span class="hljs-string">"./App.{js,jsx,ts,tsx}"</span>,
    <span class="hljs-string">"./&lt;custom directory&gt;/**/*.{js,jsx,ts,tsx}"</span>,
  ],
  <span class="hljs-attr">theme</span>: {
    <span class="hljs-attr">extend</span>: {},
  },
  <span class="hljs-attr">plugins</span>: [],
};
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/code-1.png" alt="A screenshot of tailwind.conf.js file after adding path to components" width="600" height="400" loading="lazy">
<em>tailwind.conf.js file after adding paths to components</em></p>
<p>In the above example, you can replace <code>&lt;custom directory&gt;</code> with your directory's real name.</p>
<h2 id="heading-how-to-configure-nativewind-with-babel">How to Configure NativeWind with Babel</h2>
<p>You'll also need to configure NativeWind with Babel. To do this, include the NativeWind plugin in your project's <code>babel.conf.js</code> file:</p>
<pre><code class="lang-javascript">plugins: [<span class="hljs-string">"nativewind/babel"</span>],
</code></pre>
<p>The <code>babel.conf.js</code> file would look like this after adding the NativeWind plugin:</p>
<pre><code class="lang-js"><span class="hljs-built_in">module</span>.exports = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">api</span>) </span>{
  api.cache(<span class="hljs-literal">true</span>);
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">presets</span>: [<span class="hljs-string">"babel-preset-expo"</span>],
    <span class="hljs-attr">plugins</span>: [<span class="hljs-string">"nativewind/babel"</span>],
  };
};
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/code2-2.png" alt="babel.conf.js file after adding nativewind plugin" width="600" height="400" loading="lazy">
<em>babel.conf.js file after adding nativewind plugin</em></p>
<p>By including the NativeWind plugin in the Babel configuration file you ensure that NativeWind's functionality is properly incorporated into your project's JavaScript codebase.</p>
<p> 🎉With this, NativeWind has been successfully integrated into your Expo app. The next step is to begin styling the app with NativeWind.</p>
<h2 id="heading-how-to-style-with-nativewind">How to Style with NativeWind</h2>
<p>To begin styling with NativeWind, go to your project's <code>App.js</code> file or the component you would like to style, which would look like this by default:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { StatusBar } <span class="hljs-keyword">from</span> <span class="hljs-string">"expo-status-bar"</span>;
<span class="hljs-keyword">import</span> { StyleSheet, Text, View } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-native"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.container}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Text</span>&gt;</span>Open up App.js to start working on your app!<span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">StatusBar</span> <span class="hljs-attr">style</span>=<span class="hljs-string">'auto'</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">const</span> styles = StyleSheet.create({
  <span class="hljs-attr">container</span>: {
    <span class="hljs-attr">flex</span>: <span class="hljs-number">1</span>,
    <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">"#fff"</span>,
    <span class="hljs-attr">alignItems</span>: <span class="hljs-string">"center"</span>,
    <span class="hljs-attr">justifyContent</span>: <span class="hljs-string">"center"</span>,
  },
});
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/appjs-default.png" alt="App.js boilerplate code" width="600" height="400" loading="lazy">
<em>App.js boilerplate code</em></p>
<p>Next, modify your component to get rid of any instances of <code>StyleSheet</code> abstraction. In this example, we'll modify the <code>App.js</code> code. After adjustments, we should have something like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { StatusBar } <span class="hljs-keyword">from</span> <span class="hljs-string">"expo-status-bar"</span>;
<span class="hljs-comment">// import { StyleSheet, Text, View } from "react-native";</span>
<span class="hljs-keyword">import</span> { Text, View } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-native"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="hljs-comment">// &lt;View style={styles.container}&gt;</span>
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'flex-1 justify-center items-center bg-white'</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Text</span>&gt;</span>Open up App.js to start working on your app!<span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">StatusBar</span> <span class="hljs-attr">style</span>=<span class="hljs-string">'auto'</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span></span>
  );
}

<span class="hljs-comment">// const styles = StyleSheet.create({</span>
<span class="hljs-comment">//   container: {</span>
<span class="hljs-comment">//     flex: 1,</span>
<span class="hljs-comment">//     backgroundColor: "#fff",</span>
<span class="hljs-comment">//     alignItems: "center",</span>
<span class="hljs-comment">//     justifyContent: "center",</span>
<span class="hljs-comment">//   },</span>
<span class="hljs-comment">// });</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/newww.png" alt="App.js component after modification " width="600" height="400" loading="lazy">
<em>App.js component after modification</em></p>
<p>In the modified codeblock, we remove all occurrences of <code>StyleSheet</code> abstractions, including the import statement for <code>stylesheet</code> and the <code>StyleSheet.create</code> function, and we replace <code>style</code> with <code>className</code> in the <code>App.js</code> return function.</p>
<p>Having cleared that up, all you need to do is write Tailwind CSS classes into your app <code>className</code> to begin implementing Tailwind CSS in your application. You'll see this in a bit as we build a simple login screen with NativeWind.</p>
<h2 id="heading-how-to-build-a-simple-login-screen">How to Build A Simple Login Screen</h2>
<p>Now, let's dive into building a simple login screen using NativeWind. We'll continue with the initial setup in the <code>App.js</code> file and gradually add components to create the login UI.</p>
<p>First, let's replace the existing code in the <code>App.js</code> file with the following:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { StatusBar } <span class="hljs-keyword">from</span> <span class="hljs-string">"expo-status-bar"</span>;
<span class="hljs-keyword">import</span> { Text, View } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-native"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'flex-1 justify-center items-center bg-white'</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">StatusBar</span> <span class="hljs-attr">style</span>=<span class="hljs-string">'auto'</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Text</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'text-center mt-3 text-2xl font-light text-orange-300'</span>&gt;</span>
        Login
      <span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
      {/* Additional components goes here */}
    <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span></span>
 );
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/firstt.png" alt="Starter code for login screen UI" width="600" height="400" loading="lazy">
<em>Starter code for login screen UI</em></p>
<p>The code above imports the essential components from React Native and Expo. We then use a <code>View</code> component to define the structure of our login screen, which is styled with NativeWind's utility classes. Inside the <code>View</code>, we have a <code>Text</code> component that displays "Login" with styling applied using NativeWind classes.</p>
<p>Next, you can add your login form components, such as username and password input fields, a login button, and any other necessary elements. Here is an example of how you can extend the login screen:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { StatusBar } <span class="hljs-keyword">from</span> <span class="hljs-string">"expo-status-bar"</span>;
<span class="hljs-keyword">import</span> { Text, View, TouchableOpacity, TextInput } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-native"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'flex-1 justify-center items-center bg-white'</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">StatusBar</span> <span class="hljs-attr">style</span>=<span class="hljs-string">'auto'</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Text</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'text-center mt-3 text-2xl font-light text-orange-300'</span>&gt;</span>
        Login
      <span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
      {/* Additional components goes here */}
      <span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'mt-5 mx-5'</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">View</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Text</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'text-gray-400'</span>&gt;</span>EMAIL:<span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">TextInput</span>
            <span class="hljs-attr">placeholder</span>=<span class="hljs-string">'Enter Email...'</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">'border border-dotted p-2 text-gray-500 border-amber-400 mt-1'</span>
          /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'mt-3'</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Text</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'text-gray-400'</span>&gt;</span>PASSWORD:<span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">TextInput</span>
            <span class="hljs-attr">secureTextEntry</span>
            <span class="hljs-attr">placeholder</span>=<span class="hljs-string">'Enter Password...'</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">'border text-gray-500 border-dotted p-2 border-amber-400 mt-1'</span>
          /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">TouchableOpacity</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'bg-orange-300 p-3 mt-4'</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Text</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'text-center text-base text-white'</span>&gt;</span>Login<span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">TouchableOpacity</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">Text</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'text-center font-normal text-gray-500 text-base mt-3'</span>&gt;</span>
          OR
        <span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'mt-4'</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">TouchableOpacity</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'flex flex-row items-center justify-center p-2 bg-orange-300'</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Text</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'text-white mx-2 text-sm'</span>&gt;</span>Sign In With Google<span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">TouchableOpacity</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'mt-6 flex-row justify-center'</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Text</span> <span class="hljs-attr">className</span>=<span class="hljs-string">''</span>&gt;</span>New to FreeCodeCamp? <span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">TouchableOpacity</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Text</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'text-amber-500'</span>&gt;</span>Create an Account<span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">TouchableOpacity</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span></span>
  );
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/nextend-1.png" alt="Extended login screen UI with additional components " width="600" height="400" loading="lazy">
<em>Extended login screen UI with additional components</em></p>
<p>In this expanded version, we've included <code>TextInput</code> components for the username and password input fields, as well as a <code>TouchableOpacity</code> for the login button. Styling is done with NativeWind's utility classes to provide a clean and consistent appearance.</p>
<p>Furthermore, once you've finished creating your login screen using NativeWind in your React Native Expo project, you'll want to test it to check if everything works properly. You can do this by running this command on your terminal:</p>
<pre><code class="lang-bash">expo start
</code></pre>
<p>This command will launch the bundler and generate a QR code. To open the app, scan the QR code displayed in the terminal with your emulator's camera, or press "a" for Android or "i" for iOS.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/Screenshot_20240223-015329.png" alt="Output of the code in an emulator" width="600" height="400" loading="lazy">
<em>Output of the code in an emulator</em></p>
<p>If you need to, you can access <a target="_blank" href="https://github.com/thejohncaleb/simpleproject">the complete project code</a> on GitHub.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Integrating Tailwind CSS into a React Native Expo project with NativeWind has various benefits, including increased developer efficiency, code consistency, and performance. Developers can easily create amazing mobile applications by leveraging the power of Tailwind CSS's utility-first approach and React Native's native features.</p>
<p>NativeWind makes it easy to apply Tailwind CSS to your React Native Expo app. Using Tailwind CSS in your mobile app development workflow opens up new possibilities for UI design and customization.</p>
<p>Remember, if you have any questions or just want to say hi, feel free to reach me on <a target="_blank" href="https://twitter.com/thejohncaleb">X(Twitter)</a> or my <a target="_blank" href="https://thejohncaleb.netlify.app/contact">website</a>. :)</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
