Technically Speaking

React Native Apps styled with Material Design

React Native is the development platform if you are a startup and thinking about developing for both iOS and Android. Apart from containing a ton of source material and community support, development happens in JavaScript. JavaScript is a language that is easy to grasp. Developers are quite likely to have come across JavaScript at least once in their lives. Facebook is its the main contributor and initiator.

Orpheus Digital recently moved from Cordova to React Native. Cordova basically serves web pages in an embedded browser. This has serious performance bottle-necks, specially on budget or mid-range devices. However, Cordova had been around for a longer time therefore the community was larger and more varied. This strong point was being exhausted slowly as React Native was maturing and collecting a strong community.

The strong community resulted in intricate tool kits to make development easier. One of these tools is Expo. We at Orpheus Digital are fans of this tool. This toolkit makes coding production-ready mobile apps a breeze. It takes care of all the mundane tasks and provides infinitely helpful extras like OTA debugging. Code-wise there is not much that differs from vanilla React Native development.

StoreBoss is an app based on this stack that we created. The first app we made using this stack is also StoreBoss. The link #ReactNative will get you to the other articles we have regarding this mobile development stack.

Let’s assume that you have already set up React Native and Expo (seemingly straightforward process that is provided in their respective websites). We will now move onto the material design framework that we, at Orpheus Digital, also use!

React Native Paper

This is the Material Design framework we will be using. Installing this framework is as straightforward as it can get:

yarn add react-native-paper

If you are not using Expo, you would also have to run,

yarn add react-native-vector-icons
react-native link react-native-vector-icons

This adds the library to our project. Now we will use it in our code to render some Material Designed UI elements.

The React Native Code

Startup Code

We like to isolate the starter code from the actual app. So we will have have two JS files: one named App.js which will contain our starter code and another called MainScreen.js (in a folder called src) which will contain our first actual UI.

import * as React from 'react';
import { Platform, StatusBar } from 'react-native';
import { DefaultTheme, Provider as PaperProvider } from 'react-native-paper';
import MainScreen from './src/MainScreen';

These import statements all reflect the aforementioned structure of our app. PaperProvider is the root component that our Main component should be wrapped under for the theme to work.

We will also look into defining our own colors for the app, hence the import statement for DefaultTheme.

const theme = {
  roundness: 2,
  colors: {
    primary: '#3498db',
    accent: '#f1c40f',

The ellipsis (triple dot notation) allows you to only modify the parameters of the theme that you want to while keeping the other parameters unchanged. We have defined our own roundness parameter, and primary & accent colors.

Next, we will code our Main component.

export default function Main() {
  return (
    <PaperProvider theme={theme}>
		<StatusBar barStyle={Platform.OS === 'ios' ? "dark-content": "light-content"} />
		<MainScreen />

We specify the custom theme we created earlier as a parameter for the PaperProvider. The StatusBar element refers to the area of the UI where the time, battery status…etc are shown. We are using a neat trick to make the content area darker or lighter based on the OS for improved legibility using the Platform React Native API.

MainScreen Code

Next we will layout our Appbars and buttons for our main UI screen.

import React from 'react';
import { Text, View, Alert } from 'react-native';
import { Button, Appbar } from 'react-native-paper';

The good thing about the Paper framework is that the components need to be imported as required. This is a good thing for two different reasons:

  1. Decreases overhead – you import only what you need for that view
  2. Improves flexibility – maybe you want to use a button from another library in just one screen
export default class MainSceen extends React.Component {
    constructor (props) {
        this.state = {
	render () {
		return ([
			<Appbar.Header key="1">
			  <Appbar.Action icon="filter" onPress={() => {
				Alert.alert("Alert", "You pressed on the filter button!");
			<View key="2" style={{margin: 10}}>
				<Button icon="camera" mode="contained" onPress={() => Alert.alert("Alert", "You pressed on the contained button!")}>
					Press me
				<Button icon="camera" mode="outlined" onPress={() => Alert.alert("Alert", "You pressed on the outlined button!")} style={{marginTop: 10}}>
					Press me


This is our entire MainScreen.js A relatively new feature in React Native is the ability to use a key parameter in the return statement of the render() function to string together different components without having to wrap the components in a parent element. The individual components are instead provided as an array.

Also note how the Appbar component is consumed.

Now, the project can be run using the start command

yarn start

The output app will look similar to this on the two different platforms. The main reason for our liking of the React Native Paper library when opting for a material design interface is how the styling adapts to more of an iOS-like theme when the app is run on iOS.

The interaction with the buttons reveals the ripple effects.

A screenshot from the React Native project running on an Android environment
Our test app running on Android
A screenshot from the React Native project running on an iOS environment
Our test app running on iOS

Thus, we conclude the Technically Speaking post for today. The project can be accessed from our GitHub repository