Back to blog

NativeBase Vs Chakra UI: A comparison

Sankalp Pandey· Software Engineer·July 15, 2022·9 min read
NativeBase Vs Chakra UI: A comparison

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.

  1. Custom themes
  2. Style Props
  3. Design tokens

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

Adding custom theme in Chakra UI:

// 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>

Adding custom theme in NativeBase:

// 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 palette 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.

Note: 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. 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 are components that make 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',
  },
};

Design tokens for colors.

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, the 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 for background-clip CSS attribute. Useful when creating text gradients.
  • backgroundClip: The typical background-clip CSS attribute. Useful when creating text gradients.

For NativeBase, we can add gradient support using the following style props.

  • bg: Shorthand for background.
  • colors: Takes the array of colors we want to apply to the linear gradient.
  • start: This prop is passed under the linearGradient object and denotes the starting point for the color. We can imagine this as a grid system with a starting point.
  • end: This prop is passed under the linearGradient 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"

Now, let us see how to implement the gradient in Chakra and NativeBase by creating a simple gradient from green.200 to pink.500.

The gradient implementation in Chakra:

<Box w='100%' h='200px' bgGradient='linear(to-r, green.200, pink.500)' />

The gradient implementation in NativeBase:

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 gridGap prop. NativeBase uses the space prop.

Chakra UI Grid 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>

The above code snippet will yield this output:

Chakra UI grid output

Let us see how we can use the 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.

Code snippet with direction as row:

<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>

Output using space prop in direction row

Code snippet with direction as column:

<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>

Output using space prop in direction column

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>

The as Prop

The 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>

Table

For organizing data, Chakra UI offers a 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 table variants and see how we can play with the variant prop to attain different types of tables.

Table with variant 'simple':

<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>

Example of table with variant given as simple

Table with variant 'striped':

<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>

Example of table with variant given as striped

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 if props remain shallow-equal. Make sure that everything in the renderItem passes as a prop (e.g. extraData) that is not equal after updates. Otherwise, the UI may not get updated. This includes the data 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.
  • By default, the list looks for a key prop on each item and uses it for the React key. Alternatively, you can provide a custom keyExtractor 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>
  );
}

Selection list output

Selection list output continued

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 Chakra UI are open-source.

Q. Is NativeBase and Chakra UI customizable?

Yes, both NativeBase and Chakra UI 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 React Native project, we run the following command:

npx react-native init MyApp --template @native-base/react-native-template