Written by Hussain Arif✏️
In this article, we will learn what headless component libraries are and when to use them, as well as learn about popular options for headless UI libraries in the React Native ecosystem.
Here’s what we’ll discuss today:
- What is a headless UI library, and what problems can it solve?
- Tamagui
- NativeWind
- Dripsy
- Gluestack
- Comparison table
You can find the source code repositories for the examples of Tamagui, NativeWind, Dripsy, and Gluestack on my GitHub.
What is a headless UI library, and what problems can it solve?
As developers, we often build complex apps and websites for clients. This involves components that are complicated to build and very tricky to style.
In many cases, building custom components from scratch is a demanding and time-consuming endeavor because we have to look after a plethora of requirements, which may include:
- Making sure that the component works as intended across all platforms and browsers
- Ensuring that it is performant and does not have any memory leaks
- Moreover, confirm whether the dependencies of that custom element are up to date
As an example, let’s take this ListBox
component: As you can see, replicating this behavior in a custom React component is not easy at all. So how do we fix this problem? This is where headless component libraries come in.
They are essentially a set of components that provide the logic, processing, and API, but rely on the developer for styling. In simpler words, these libraries handle all the heavy lifting and all we have to do is to make them look good.
Now that we have learned about the fundamentals of this concept, let’s now explore some popular component libraries for React Native.
Tamagui
Tamagui is a library that provides universally styled components for both React and React Native platforms. Its biggest advantage is that since it supports React and Native, the styling code is unified between both web and mobile platforms. Furthermore, the team also maintains that performance is better than other competing libraries.
To integrate Tamagui into your Expo app, follow these instructions. When that’s done, write the following code in your App.js
file:
import { useFonts } from "expo-font";
import { Button, Paragraph, TamaguiProvider, Theme, YStack } from "tamagui";
import config from "./tamagui.config";
export default function App() {
const [loaded] = useFonts({
Inter: require("@tamagui/font-inter/otf/Inter-Medium.otf"),
InterBold: require("@tamagui/font-inter/otf/Inter-Bold.otf"),
});
//Render the UI as soon as the resources are loaded
if (!loaded) {
return null;
}
return (
<TamaguiProvider config={config}>
{/*Render a View with dark theme*/}
<Theme name={"dark"}>
<YStack f={1} jc="center" ai="center" backgroundColor={"pink"}>
{/*Render some text onto the screen*/}
<Paragraph color="black" jc="center" fontSize={50} lineHeight={80}>
Black
</Paragraph>
</YStack>
</Theme>
{/*Render another view with light theme*/}
<Theme name="light">
<YStack f={1} ai="center" jc="center" backgroundColor="black">
<Paragraph color="pink" jc="center" fontSize={50} lineHeight={80}>
Pink
</Paragraph>
</YStack>
</Theme>
{/*Render a third View with dark theme and display a button*/}
<Theme name="dark">
<Button color={"$pink10Dark"}> I am a dark button</Button>
</Theme>
</TamaguiProvider>
);
}
Let’s test it out! To run this code, run this Bash command:
npm run start-android
Pros and cons of Tamagui
Here are a few factors that make it a great library:
- Supports Expo CLI, which gives developers more choice when it comes to building React Native apps
- The library uses a concept called tokens, which is a feature that offers detailed control over the styling and theming of components
- It’s faster than other component libraries
- As shown in the code above, Tamagui allows developers to have multiple theming options on the same screen
However, there are some things that I didn’t like about Tamagui:
- The setup process for Expo apps is tedious
- Documentation is not easy to follow. As a result, this might deter new developers from using the Tamagui technology
- The library does not follow Tailwind’s styling conventions, which prevents us from using class names to style our React components
NativeWind
NativeWind is another tool that allows developers to share styling code between React and React Native platforms. However, unlike Tamagui, its key feature is that it lets users use Tailwind’s scripting language to decorate UI elements.
First, to integrate NativeWind in your Expo app, follow these steps. Next, in your tailwind.config.app
, add the following lines of code:
module.exports = {
content: [
"./app/**/*.{js,jsx,ts,tsx}",
"/*.{js,jsx,ts,tsx}",
"./App.{js,jsx,ts,tsx}", //ensures that App.js is styled as well
],
//further code..
Let’s now see it in action! To do so, replace all the code in App.js
with the following:
import { StatusBar } from "expo-status-bar";
import { Text, View } from "react-native";
import "./global.css";
export default function App() {
return (
//apply Tailwind styling to our React Native elements..
<View className="flex-1 items-center justify-center bg-blue-400">
<Text className="px-8 text-lg text-rose-800">
This style is being applied with NativeWind
</Text>
<StatusBar style="auto" />
</View>
);
}
To run the code, execute this Bash command:
npx expo start -c #clear the cache and then run the app
Pros and cons of NativeWind
Here are a few key features that help NativeWind stand out:
- Uses Tailwind’s styling convention, which means that designing components is relatively easier than Tamagui
- Small runtime, which brings great performance to the table
- Easy to set up
- Clear documentation
- Supports Expo
However, there was one thing that made it unappealing:
- At the time of writing of this article, the library currently relies on an older version of TailwindCSS
Dripsy
Dripsy is another React Native library that, like Tamagui and NativeWind, aids users in unifying styling code between web and mobile. Moreover, compared to its counterparts, Dripsy has a remarkably simple setup process.
To use Dripsy in your app, install it like so:
npm install dripsy
That’s it! To use this library, write the following code in your App.js
file:
import { StatusBar } from "expo-status-bar";
import { View, Text } from "dripsy";
import { DripsyProvider } from "dripsy";
export default function App() {
return (
<DripsyProvider>
<View
//use the 'sx' prop to style our component
sx={{
height: "100%",
backgroundColor: "green",
}}
>
<Text sx={{ marginY: 100, color: "rgb(255,255,255)", fontSize: 30 }}>
This was styled with Dripsy
</Text>
<StatusBar style="auto" />
</View>
</DripsyProvider>
);
}
Let’s now see it in action! Run this piece of code in your terminal:
npx expo start -c
Pros and cons of Dripsy
Here are some of the reasons why Dripsy might be suitable for you:
- Uses the
sx
prop for more control over UI styling. Furthermore, this prop is also memoized out of the box, thus promising a responsive app - Lets developers use custom fonts. As discussed before, this allows for more customization options
- Can override themes
- The setup process is a walk in the park as compared to other alternative libraries
But one thing you want to look out for is:
- This library is not frequently updated. As of this article, the latest update was four months ago
Gluestack
Just like the other libraries mentioned in this article, Gluestack is another unstyled component library. Originally a part of NativeBase, the developer team created this library to prevent bloat and enhance maintainability of the project.
To install Gluestack in an Expo project, run this Bash command:
npm i @gluestack-ui/themed @gluestack-style/react react-native-svg@13.4.0
This block of code demonstrates sample usage of the Gluestack technology:
import { GluestackUIProvider, Text, Box, config } from "@gluestack-ui/themed";
export default function App() {
return (
//use the default config
<GluestackUIProvider config={config.theme}>
{/*Create first Box element with black background color*/}
<Box
width="100%"
height="50%"
justifyContent="center"
alignItems="center"
bgColor="black"
>
<Text color="white">This text was styled using Gluestack</Text>
</Box>
{/*Create second Box element with pink background color*/}
<Box
width="100%"
height={"50%"}
justifyContent="center"
alignItems="center"
bgColor="pink"
>
<Text color="blue">This second block of text was styled as well</Text>
</Box>
</GluestackUIProvider>
);
}
Pros and cons of Gluestack
Here are a few factors that make it a decent choice for your project:
- Provides animations out of the box: This means that users don’t need to manually implement animations in their app
- Extensive theming: Gluestack’s theming config resembles Tamagui’s, which means developers need to use tokens to customize and style their components. This results in a shallower learning curve
- Extensive list of components, which ensures that users can easily pick and choose between Native components depending on their needs
However, there are some things that you might want to consider before integrating Gluestack in your app:
- At the time of this article, the library relies on an older version of
react-native-svg
. This may break the app due to dependency conflicts:
Comparison table
Here is a table that summarizes all the key features of the libraries discussed earlier:
Aspect | Tamagui | NativeWind | Dripsy | Gluestack |
---|---|---|---|---|
Styling convention | Custom tokens | TailwindCSS | `sx` prop for styling | Custom tokens |
Performance | Faster than others | Small runtime, good performance | Responsive, memoized `sx` prop | Substantially faster than NativeBase. Slower than other alternatives, but still competitive |
Setup process | Tedious for Expo apps, easy for other integrations | Easy to setup for all integrations | Straightforward setup for all integrations | Straightforward setup for all integrations |
Documentation | Not easy to follow (but [LogRocket has a good guide](https://blog.logrocket.com/tamagui-react-native-create-faster-design-systems/)) | Clear documentation | Detailed and easy to follow | Details and easy to follow |
Theming options | Multiple theming on one screen. Can override themes | Same as TailwindCSS | Can override themes | Can override themes |
Custom fonts | No | No | Yes | No |
Follows Tailwind’s convention | No | Yes | No | No |
Update frequency | Frequent updates | Regular updates | Infrequent updates | Frequent updates |
Integrations | React Native, Next.js, React | React Native, Next.js, React | React Native, Next.js | React Native, React, Next.js |
Conclusion
Here are the source code repositories for the examples of Tamagui, NativeWind, Dripsy, and Gluestack.
In this article, we briefly discussed the importance of headless component libraries. Furthermore, we also compared some of the most popular headless component technologies for React Native.
In my personal projects, I use NativeWind because it follows Tailwind’s styling language, thus making it effortless to decorate and design UI components. Thank you so much for reading!
LogRocket: Instantly recreate issues in your React Native apps.
LogRocket is a React Native monitoring solution that helps you reproduce issues instantly, prioritize bugs, and understand performance in your React Native apps.
LogRocket also helps you increase conversion rates and product usage by showing you exactly how users are interacting with your app. LogRocket's product analytics features surface the reasons why users don't complete a particular flow or don't adopt a new feature.
Start proactively monitoring your React Native apps — try LogRocket for free.
Top comments (0)