How I Expo

How I Expo

I've been dealing with Expo for a couple of years now, here and there. I've faced many challenges, especially with build errors, so here are the best practices I follow. As of February 2025, this guide has been tested and proven to work for setting up an Expo project!

1. Create Your App

Start by creating a new Expo app using the latest version of the Expo CLI. This will install the required dependencies.

npx create-expo-app@latest

2. Set Up Your Splash Screen

Prepare a 1024x1024 image and note the background color. Create three versions of the image with the following names:

  • splash-icon.png
  • icon.png
  • adaptive-icon.png

Replace the existing images in:

assets/images

Run the app on iOS:

npm run ios

Fixing the Background Color

Changing the background color in app.json alone will not work. You need to add the following line:

"plugins": [
    "expo-router",
    [
        "expo-splash-screen",
        {
            "image": "./assets/images/splash-icon.png",
            "imageWidth": 200,
            "resizeMode": "contain",
            "backgroundColor": "#070707" // No effect without additional config
        }
    ]
],

Now, add this configuration to app.json and reload the simulator (press r). This should properly apply the background color:

"splash": {
    "image": "./assets/images/splash-icon.png",
    "backgroundColor": "#070707"
},

3. Install NativeWind (Tailwind for React Native)

Tailwind CSS is great for styling. Here’s how to set it up correctly:

npm i tailwindcss@3.3.2
npm install nativewind
npx tailwindcss init

Update your tailwind.config.js:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./app/**/*.{js,jsx,ts,tsx}"],
  presets: [require("nativewind/preset")],
  theme: {
    extend: {},
  },
  plugins: [],
};

4. Configure Metro and Babel

Create and configure metro.config.js:

touch metro.config.js
const { getDefaultConfig } = require("expo/metro-config");
const { withNativeWind } = require("nativewind/metro");

const config = getDefaultConfig(__dirname);

module.exports = withNativeWind(config, { input: "./global.css" });

Create and configure babel.config.js:

touch babel.config.js
module.exports = function (api) {
  api.cache(true);
  return {
    presets: [["babel-preset-expo", { jsxImportSource: "nativewind" }], "nativewind/babel"],
    plugins: ["react-native-reanimated/plugin"],
  };
};

5. Test Tailwind Setup

Modify app/_layout.tsx to test if Tailwind styles are working:

import { View, Text } from "react-native";
import React from "react";

const Index = () => {
  return (
    <View className="flex-1 items-center justify-center">
      <Text className="text-white">index</Text>
    </View>
  );
};

export default Index;

Now, kill and restart the simulator, and Tailwind styles should be working!

6. Eject the Expo Project (If Needed)

If you need to customize native code, eject the project:

npx expo prebuild

This will generate the necessary Android and iOS directories, allowing native modifications.


Following these steps ensures a smooth Expo setup with best practices for splash screens and Tailwind styling. 🚀