Matthieu Napoli Software Consultant





Writing solid React Native applications just got easier with TheCodingMachine's boilerplate.

TL;DR

We are open sourcing a React Native boilerplate for creating mobile applications. This boilerplate is a template project that builds on all the experience accumulated writing mobile applications at TheCodingMachine.

The boilerplate is based on libraries such as Redux and Redux-Saga and provides a solid architecture that facilitates separation of concerns between the UI, state management and business logic.

Introduction

There are more and more mobile applications being built at TheCodingMachine, and every project is the opportunity to learn something new to make the next one even better.

What we've learned over time is that while React Native is a great tool to build iOS and Android applications, keeping the code organized and maintainable can become a challenge.

Instead of re-installing the same libraries and re-writing the same architecture for every project, we've decided to put all that into a boilerplate. On top of that, we have documented every file and piece of code in this boilerplate so that all the choices we made are explained and explicit.

What about existing boilerplates? We cover that at the end of the article.

Architecture

The driving goal of the architecture of the boilerplate is separation of concerns. Namely:

Presentational components are separated from containers (aka "screens"). Presentational components are small components that are concerned with how things look. Containers usually define whole application screens and are concerned with how things work: they include presentational components and wire everything together. If you are interested you can read more about it here.

State is managed using global Redux stores . When applications grow, sharing state and its changes can become very hard. Questions like "How can I access this data?" or "When did this change?" are common, just like passing data around components just to be able to use it in nested components. With Redux, state is shared using global stores, and changes are predictable: actions are applied by reducers to the state. While the pattern can be a bit much for small projects, the clear separation of responsibilities and predictability helps with bigger applications. If you are interested you can read more about it here.

Application side-effects (API calls, etc.) are separated from UI and state manipulation using Redux Saga. Using Redux Saga has two benefits: keeping application side-effects and related business logic out of UI components, as well as executing that logic in an asynchronous way without ending in callback hell. Sagas are triggered by Redux actions and can also trigger Redux actions to alter state. By using JavaScript generators ( yield ), sagas are written in a synchronous-like manner while still executing asynchronously.

What's in the box?

On a more technical level, the boilerplate contains:

a React Native application (in "ejected" mode to allow using dependencies that rely on native code)

Redux to help manage state

Redux Persist to persist the Redux state

Redux Saga to separate side-effects and logic from state and UI logic

React Navigation to handle routing and navigation in the app, with a splash screen setup by default

reduxsauce to facilitate using Redux

apisauce to make axios even better

prettier and eslint preconfigured for React Native

In regards to the architecture described above, the boilerplate provides the following directory layout:

The boilerplate includes an example (displaying the current weather temperature) from UI components to the saga. The example is easy to remove so that it doesn't get in the way.

Getting started

To create a mobile application using the boilerplate, head over to the GitHub repository. The rest takes only a few steps:

clone the repository: git clone https://github.com/thecodingmachine/react-native-boilerplate

remove the previous git history: rm -rf .git/

install the npm dependencies by running yarn

rename the React Native project to your own project name: yarn run rename -- <YourProjectName> (the default name is Boilerplate )

(the default name is ) remove the LICENSE file and the "License" section from the README if your project is not open source

That's it! The application is fully functional, for example you can run react-native run-android to start the Android application or react-native run-ios for the iOS one. If you have any issue, check out the README for more detailed instructions.

You can start exploring the App directory to checkout the example included, or begin coding your application.

What about other boilerplates?

We looked into existing boilerplates before starting this project, and while many of them are awesome, we did not find what we were looking for.

The most popular is mcnamee's Starter Kit, which is unfortunately limited by Expo and misses Redux Saga.

If we look at the rest (and ignore unmaintained projects), many popular boilerplates are too opinionated: they include 3rd party services or very strong architecture choices that we were not comfortable with. To name a few: Snowflake runs with a Hapi Server running on Redhat OpenShift, Hasura's boilerplate uses Hasura's SaaS for authentication, Apollo's StarterKit is targeted at GraphQL using Apollo, the Meteor Boilerplate targets Meteor…

Finally some did not contain the architecture we were looking for (the separation of concerns with Redux, Sagas, etc.), for example re-start.

One interesting exception was Ignite IR Boilerplate "Andross", but after consideration we decided not to use it because of the large amount of unnecessary code/components it provided.

Looking at all those boilerplates was interesting! It helped us see the common issues and mistakes to avoid to build something that stands out:

"you don't know what you get": the goal and the content of the boilerplate must be explicit

"using a boilerplate means making the code of someone else our own": every choice and piece of code in the boilerplate must be explained and documented

"bloated boilerplates are too much to handle": the boilerplate must stick to a clear goal and not become an aggregate of random packages and tools

What's next?

Since we are the first users of the boilerplate our goal is to keep it up to date. We are actively looking into supporting the latest React Native release, and we will continue to improve it continuously.

We are also documenting other parts related to building mobile applications that cannot be solved by code. For example we have documented how to deploy beta builds for TestFlight and the Google Play Store.

Follow the project to keep updated!

About the author

Matthieu is a software consultant. He is the co-editor of PSR-11 and PSR-15 as well as the author of open source projects like PHP-DI and Bref.