npx create-expo-app --template
# redux
npm i @reduxjs/toolkit react-redux
# UI stuff
npm i @expo-google-fonts/lato
npx expo install expo-image
npx expo install expo-linear-gradient
# data fetching
npm i axios
npm i @tanstack/react-query
# nativewind initialization
npm i nativewind
npm i --save-dev tailwindcss
npx tailwindcss init
npm i --dev tailwindcss@3.3.2
# storage
npm i @react-native-async-storage/async-storage
If using React Navigation, then follow these steps:
npm install @react-navigation/native
npx expo install react-native-screens react-native-safe-area-context
npm install @react-navigation/native-stack
- Add the files to allow tailwind styling for in the
tailwind.config.js
:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./app/**/*.{js,jsx,ts,tsx}", "./components/**/*.{js,jsx,ts,tsx}"],
theme: {
extend: {},
},
plugins: [],
};
- Add nativewind plugin to
babel.config.js
:
module.exports = function (api) {
api.cache(true);
return {
presets: ["babel-preset-expo"],
plugins: ["nativewind/babel"],
};
};
- Clear cache with
npx expo start -c
- If something isn't working, do
npm i --dev tailwindcss@3.3.2
npm i clsx
npm i tailwind-merge
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
The className
attribute when using nativewind will not be recognized, so to get rid of that annyoing error, follow these steps:
-
Create an
my-app.d.ts
in the root of your folder, and paste in the following triple directive:/// <reference types="nativewind/types" />
- alternatively, just paste this line at the top of every tsx file.
-
Add the filepath to the
types
key in yourpackage.json
, letting your app know that this is the types library you want to use."types": "my-app.d.ts"
- Import from expo google fonts, and the
useFonts()
hook to load them - Name your fonts shorter names, and use those names to refer to them when creating the theme.
import {
useFonts,
Lato_300Light,
Lato_400Regular,
Lato_700Bold,
} from "@expo-google-fonts/lato";
export default function App() {
const [loaded] = useFonts({
"lato-300": Lato_300Light,
"lato-400": Lato_400Regular,
"lato-700": Lato_700Bold,
});
// render splash screen while app is loading
if (!loaded) {
return null;
}
// return app here
}
// theme.js
module.exports = {
fontFamily: {
lato: ["lato-400", "sans-serif"],
latoLight: ["lato-300", "sans-serif"],
latoBold: ["lato-700", "sans-serif"],
},
};
/** @type {import('tailwindcss').Config} */
const { fontFamily: ff } = require("./theme");
module.exports = {
content: [
"./App.{js,jsx,ts,tsx}",
"./screens/**/*.{js,jsx,ts,tsx}",
"./components/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {
fontFamily: ff,
},
},
plugins: [],
};
With the above code, we are loading the fonts and mapping them like this:
lato-400 -> lato -> font-lato
lato-300 -> latoLight -> font-latoLight
lato-700 -> latoBold -> font-latoBold
import { StyleSheet } from "react-native";
export const shadow_styles = StyleSheet.create({
shadow_subtle: {
shadowColor: "#000",
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.8,
shadowRadius: 2,
elevation: 5,
},
shadow_sm: {
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 1,
},
shadowOpacity: 0.22,
shadowRadius: 2.22,
elevation: 3,
},
shadow_md: {
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 4,
},
shadowOpacity: 0.3,
shadowRadius: 4.65,
elevation: 8,
},
shadow_lg: {
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 6,
},
shadowOpacity: 0.37,
shadowRadius: 7.49,
elevation: 12,
},
shadow_xl: {
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 8,
},
shadowOpacity: 0.46,
shadowRadius: 11.14,
elevation: 17,
},
shadow_2xl: {
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 12,
},
shadowOpacity: 0.58,
shadowRadius: 16.0,
elevation: 24,
},
});