What takes precedence while creating an application—back-end or front-end? For a long time, it was the back-end that got prioritized. Hitting performance benchmarks was the symbol of success. Times are changing. Today, user-experience-driven Front-end development is a priority.
As a result, developers and app designers are turning to easy-to-use UI libraries. Among them, NativeBase and Chakra UI are leading the pack. These two libraries offer easy-to-use components that help build applications with little hassle.
In this blog, we discuss:
🤔 What are the similarities and differences between the two prodigious UI libraries
💪🏽 Pros and cons of using one over the other
⚖️ When to prefer NativeBase over Chakra UI, and vice versa
What is NativeBase?
NativeBase is a free, open-source UI library for building high-quality cross-platform applications. Its documentation is simple and contains clear steps for creating reusable components. With NativeBase, app developers need to spend less time on repetitive tasks.
What is Chakra UI? 🤔
Chakra UI is a modern component library for React, used for web applications. It comes with reusable and composable React components for creating front-end apps. Its popularity comes from its simplicity, modularity, and accessibility. The library has clear explanations on how to use reusable components, reducing development time.
Why compare NativeBase and Chakra UI?
The two libraries—NativeBase and Chakra UI—are highly popular in the developer community. Both reduce application development timelines and resources needed for projects. However, there are key differences in their usability and components.
By comparing them, the goal is to set the record straight on which one to choose based on the project’s requirements.
Comparison
We will be comparing both the NativeBase and Chakra UI libraries based on three yardsticks:
- Usages
- Functions
- Components
First, we look at the similarities between the two platforms and then compare the differences.
Similarities 🟰
The following components are similar in NativeBase and Chakra UI.
- Custom themes
- Style Props
- Design tokens
Let us look at their characteristics in detail.
Custom themes
Both libraries offer a high degree of customization features. All the components in NativeBase and Chakra UI are set in the default theme by default. To customize them, we can extend the themes in both libraries.
Here is a list of customizations the two platforms provide:
- Customization based on theme tokens like colors, font sizes, line heights, etc.
- Iteration of styles, base styles, sizes, or variants
- Modification of global styles
// 1. Import `extendTheme`
import { extendTheme } from "@chakra-ui/react"
// 2. Call `extendTheme` and pass your custom values
const theme = extendTheme({
colors: {
brand: {
100: "#f7fafc",
// ...
900: "#1a202c",
},
},
})
// 3. Pass the new theme to `ChakraProvider`
<ChakraProvider theme={theme}>
<App />
</ChakraProvider>
// 1. Import the extendTheme function
import { extendTheme, NativeBaseProvider } from 'native-base';
// 2. Extend the theme to include custom colors, fonts, etc
const newColorTheme = {
brand: {
900: '#8287af',
800: '#7c83db',
700: '#b3bef6',
},
fontConfig: {
Roboto: {
100: {
normal: 'Roboto-Light',
italic: 'Roboto-LightItalic',
},
200: {
normal: 'Roboto-Light',
italic: 'Roboto-LightItalic',
},
300: {
normal: 'Roboto-Light',
italic: 'Roboto-LightItalic',
},
400: {
normal: 'Roboto-Regular',
italic: 'Roboto-Italic',
},
}
};
const theme = extendTheme({ colors: newColorTheme });
// 3. Pass the `theme` prop to the `NativeBaseProvider`
function App() {
return (
<NativeBaseProvider theme={theme}>
<App />
</NativeBaseProvider>
);
}
The above code snippets show how similar the two platforms are when customizing a theme. Both allow easy modification and addition of properties to meet preset design standards. We are importing
extendTheme
in both libraries and adding our custom requirements.Another example is the code below. It explains how we define the Color pallet in the two libraries.
const theme = extendTheme({
colors: {
brand: {
100: "#f7fafc",
// ...
900: "#1a202c",
},
},
})
Also, note that we are passing
extendTheme
as a prop
named theme
inside <ChakraProvider>
for Chakra and <NativeBaseProvider>
for NativeBase. What are ChakraProvider and NativeBaseProvider?
Every Context object comes with a Provider React component that allows consuming components to subscribe to context changes.
The Provider component accepts a
value
prop. One Provider connects to many consumers. Providers can be nested to override values deeper within the tree.In a typical React application, data is passed top-down (parent to child) via props, still such usage can be cumbersome for certain types of props (e.g. locale preference, UI theme) required by many components within an application. Context provides a way to share values like these between components without passing through every level of the tree.
The ChakraProvider and NativeBaseProvider two providers are a component that makes the theme available throughout your app. Both use React's Context API.
Style Props
Both libraries offer several shorthand variations of style props for components. Here are a few popular ones.
- m is used for margin.
- mr is used for marginRight.
- mt is used for marginTop.
- p is used for padding.
- pr is used for paddingRight.
- pt is used for paddingTop.
- py is used for padding-top and padding-bottom.
- Design tokens
Design tokens bring consistency to user interfaces. They represent spacing, color, typography, etc.
Here is an example for defining design tokens for space and colors.
const colors = {
primary: {
50: '#ecfeff',
100: '#cffafe',
......
700: '#0e7490',
800: '#155e75',
900: '#164e63',
},
};
export const spacing = {
px: 1,
1: 4,
2: 8,
3: 12,
4: 16,
5: 20,
......
72: 288,
80: 320,
96: 384,
};
Instead of using absolute values for the design, we can use the generated design tokens. Here is an example.
<Box mt="4" bg="primary.500"/>
The above code snippet depicts how we can use design tokens to make the code simpler, crisp, and clean. The above code will translate into the following code:
<View style={{ marginTop: 16, backgroundColor: 'cyan.500' }} />
Differences ⛓️
Let us explore how the two libraries differ.
Style Props
Certain style tokens like
mr
for margin-right, ml
for margin-left are similar in both NativeBase and Chakra UI. However, there are big differences in how to use Gradient
Grid Layout
as prop
and filter
. Gradient
In Chakra UI, the tokens depict the direction of the application of the gradient. For NativeBase, we use the coordinate system to achieve the same output.
For Chakra UI, we can add gradient support using any of the following style props.
bgGradient
: Shorthand for the convenient style prop to apply theme-aware gradients.
bgClip
: Shorthand forbackground-clip
CSS attribute. Useful when creating text gradients.
backgroundClip
: The typicalbackground-clip
CSS attribute. Useful when creating text gradients.
For NativeBase, we can add gradient support using the following style props.
bg
: Shorthand forbackground
.
colors
: Takes the array of colors we want to apply to the linear gradient.
start
: Thisprop
is passed under thelinearGradient
object and denotes the starting point for the color. We can imagine this as a grid system with a starting point.
end
: Thisprop
is passed under thelinearGradient
object. It denotes the ending point for the color. We can imagine this as a grid system with an ending point.
The code snippet below shows the NativeBase
props
discussed above, in action:linearGradient: {
colors: ["cyan.400", "teal.200"],
start: [0, 0],
end: [0, 1],
},
In the code snippet below, we can see supported direction shorthands and their respective values.
"to-t": "to top",
"to-tr": "to top right",
"to-r": "to right",
"to-br": "to bottom right",
"to-b": "to bottom",
"to-bl": "to bottom left",
"to-l": "to left",
"to-tl": "to top left"
"to-t": "to top",
"to-tr": "to top right",
"to-r": "to right",
"to-br": "to bottom right",
"to-b": "to bottom",
"to-bl": "to bottom left",
"to-l": "to left",
"to-tl": "to top left"
"to-t": "to top",
"to-tr": "to top right",
"to-r": "to right",
"to-br": "to bottom right",
"to-b": "to bottom",
"to-bl": "to bottom left",
"to-l": "to left",
"to-tl": "to top left"
Now, let us see how to implement the gradient in Chakra and NativeBase by creating a simple gradient from
green.200
to pink.500
<Box w='100%' h='200px' bgGradient='linear(to-r, green.200, pink.500)' />
bg={{
linearGradient: {
colors: ["cyan.400", "teal.200"],
start: [0, 0],
end: [0, 1],
},
}}
Grid Layout
For making divisions responsive, Chakra UI gives us a grid layout. It renders a
div
element. In NativeBase, we use the Stack component. For example, to provide space between the divisions, in Chakra we have the gripGap
prop. NativeBase uses the space
prop.Here's an example:
<Grid templateColumns='repeat(5, 1fr)' gap={6}>
<GridItem w='100%' h='10' bg='blue.500' />
<GridItem w='100%' h='10' bg='blue.500' />
<GridItem w='100%' h='10' bg='blue.500' />
<GridItem w='100%' h='10' bg='blue.500' />
<GridItem w='100%' h='10' bg='blue.500' />
</Grid>
Let us see how we can use
space
prop to achieve the same output in NativeBase. Point to be noted: The NativeBase Stack aligns items vertically or horizontally based on the direction prop. <Stack direction="row" mb="2.5" mt="1.5" space={3}>
<Center
size="16"
bg="primary.400"
rounded="sm"
_text={{
color: "warmGray.50",
fontWeight: "medium",
}}
>
Box 1
</Center>
<Center
bg="primary.500"
size="16"
rounded="sm"
_text={{
color: "warmGray.50",
fontWeight: "medium",
}}
>
Box 2
</Center>
<Center
size="16"
bg="primary.700"
rounded="sm"
_text={{
color: "warmGray.50",
fontWeight: "medium",
}}
>
Box 3
</Center>
</Stack>
<Stack mb="2.5" mt="1.5" direction="column" space={3}>
<Center
size="16"
bg="primary.400"
rounded="sm"
_text={{
color: "warmGray.50",
fontWeight: "medium",
}}
>
Box 1
</Center>
<Center
bg="primary.500"
size="16"
rounded="sm"
_text={{
color: "warmGray.50",
fontWeight: "medium",
}}
>
Box 2
</Center>
<Center
size="16"
bg="primary.700"
rounded="sm"
_text={{
color: "warmGray.50",
fontWeight: "medium",
}}
>
Box 3
</Center>
</Stack>
Filter
NativeBase does not support Filter directly as a
prop
. We can pass it as a style prop inside _web. If we look at the code snippets below, we can see the difference between the application of filters in the two libraries.
Chakra
<Box filter="grayscale(80%)">
Box with Filter
</Box>
NativeBase:
<Box _web={{ style: { filter: "grayscale(80%)" } }}>
Box with Filter
</Box>
as
PropThe
as
prop allows you to pass an HTML tag or component to be rendered. Say you are using a Button
component and you need to make it a link. You can compose a
and Button
like the example shown below: <Button as='a' target='_blank' variant='outline' href='https://chakra-ui.com'>
Hello
</Button>
TableThe above code snippet with variant simple The above code snippet with variant striped
For organizing data, Chakra UI offers
table
. It renders a div
that wraps the table component. This makes sure that the table does not overflow into the parent container. It also enables horizontal scrolling and prevents content from breaking lines.The component renders the following props:
display
and maxWidth
. It can also optionally accept the overflow
or overflowX
props to override the overflowX
default value of auto
rendered by this component.It comes in three variants:
simple
, striped
, and unstyled
. The default variant is simple
. We can control the sizes of the tables based on requirements. There are three sizes: sm
, md
, lg
The default size is md
.Let us look at the code snippets for all the able variants and see how we can play with
variant
prop to attain different types of tables. <TableContainer>
<Table variant='simple'>
<TableCaption>Imperial to metric conversion factors</TableCaption>
<Thead>
<Tr>
<Th>To convert</Th>
<Th>into</Th>
<Th isNumeric>multiply by</Th>
</Tr>
</Thead>
<Tbody>
<Tr>
<Td>inches</Td>
<Td>millimetres (mm)</Td>
<Td isNumeric>25.4</Td>
</Tr>
<Tr>
<Td>feet</Td>
<Td>centimetres (cm)</Td>
<Td isNumeric>30.48</Td>
</Tr>
</Tbody>
<Tfoot>
<Tr>
<Th>To convert</Th>
<Th>into</Th>
<Th isNumeric>multiply by</Th>
</Tr>
</Tfoot>
</Table>
</TableContainer>
<TableContainer>
<Table variant='striped'>
<TableCaption>Imperial to metric conversion factors</TableCaption>
<Thead>
<Tr>
.......
</Tr>
</Thead>
<Tbody>
<Tr>
........
</Tr>
</Tbody>
<Tfoot>
<Tr>
.......
</Tr>
</Tfoot>
</Table>
</TableContainer>
Selection Listcode snippet for selection list.
This is a convenient wrapper around
<VirtualizedList>
. It inherits its props (as well as those of <ScrollView>
) that aren't explicitly listed here, along with the following caveats:- The internal state vanishes when content scrolls out of the render window. Make sure data is captured in the item data or external stores like Flux, Redux, or Relay.
- The selection list is a
PureComponent
. It will not re-render ifprops
remain shallow-equal. Make sure that everything in therenderItem
passes as a prop (e.g.extraData
) that is not===
after updates. Otherwise, the UI may not get updated. This includes thedata
prop and parent component state.
- Content renders asynchronously offscreen to constrain memory and enable smooth scrolling. However, if the scrolls are faster than the fill rate, the user will momentarily see blank content. This is a tradeoff that can be adjusted to suit the needs of each application. We are working on improving it behind the scenes.
- By default, the list looks for a
key
prop on each item and uses it for the React key. Alternatively, you can provide a customkeyExtractor
prop.
Let’s look at a code snippet for the selection list.
const Example = () => {
const data = [
{
title: "Cyan",
data: ["cyan.100", "cyan.200", "cyan.300", "cyan.400", "cyan.500"],
},
{
title: "Yellow",
data: [
"yellow.100",
"yellow.200",
"yellow.300",
"yellow.400",
"yellow.500",
],
},
];
return (
<Center h="80" w="100%">
<SectionList
maxW="300"
w="100%"
mb="4"
sections={data}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) => (
<Center py="4" bg={item}>
{item.split(".")[1]}
</Center>
)}
renderSectionHeader={({ section: { title } }) => (
<Center>
<Heading fontSize="xl" mt="8" pb="4">
{title}
</Heading>
</Center>
)}
/>
</Center>
);
}
When to go for each platform?
The choice boils down to the type of application getting built. If you are looking to develop a web-exclusive application, then there is no harm in going for Chakra UI.
For cross-platform applications, NativeBase wins. It provides the ability to use the same codebase across all platforms. The latest version of NativeBase also contains features like
Multiplatform
and Accessibility
that make it more user-friendly. Frequently Asked Questions (FAQs)
Q. Is NativeBase and Chakra UI open-source?
Yes, both NativeBase and ChakraUI are open-source.
Q. Is NativeBase and Chakra UI customizable?
Yes, both NativeBase and ChakraUI are customizable and reusable.
Q. How do I add NativeBase to my project?
For Expo Project, we run the following command
expo init my-app --template @native-base/expo-template
For Next.js Project we run the following command
yarn create next-app -e
https://github.com/GeekyAnts/nativebase-templates/tree/master/nextjs-with-native-base
For the ReactNative project, we run the following command
npx react-native init MyApp --template @native-base/react-native-template