Scaffolding a project is perhaps one of the most important and common things to do during the early development stage. Depending on how a project is set up in the beginning can affect a project’s lifecycle and how things are maintained when the codebase starts growing larger.
Using a boilerplate
Most of the frontend React based projects I do start out by generating a barebones boilerplate using Facebook’s excellent and highly popular
create-react-app. For mobile applications I first decide whether or not I need to use any native based modules such as
react-native-ble-plx (for Bluetooth capabilities) and if the answer is no I use
create-react-native-app. If I do require native modules then I just use
react-native init via the react-native-cli, although I may choose to eject out of a create-react-native-app created project later, if I realize that native modules are needed.
The first directory I create if it doesn’t already exist is the project root level
src directory. The purpose of the
src directory is so that all of the JS or TS code is in one place and easier to see. It’s definitely optional but I prefer to have one. The rest of the folders are nested within the
constants directory is useful because it is a good place to easily access globally used constants. For example, if one decides to use Redux to manage state for their project it’s a good idea to have all of the constants corresponding to actions in an easily accessible place.
components directory I store all of the UI view components, there is little to no frontend logic defined in these components and I try to keep them all extended from
PureComponent with just a single
render() method. Although one may opt to use a nested folder per component with an
index.js file inside specifying the component, I usually go with
ComponentName.js to avoid ambiguity when editing files in a text editor.
In this directory I store all of my logical container components. For an in depth explanation in regards to the differences between presentational and container components refer to this excellent article by Dan Abramov. Container components do not include any presentational information and are only concerned with how things work rather than how things look.
views directory contains the screens or the page components for the application. Similar to the
components directory the components in the
views directory do not contain any business logic and are only concerned with how the data appears to the user on the screen and are all pure components.
This directory contains all of my Redux reducers which define global application state. If state is only used for a particular view I don’t mind defining local state in a container, but for things like user account details, or data used throughout the application I use reducers.
stores directory (optional)
Since I usually use Redux for state management I only have one store, but if for some reason I do require multiple stores having a
stores directory is useful.
Often times I use a set of useful utility functions throughout multiple applications, perhaps this may be functions for wrapping API calls such that they use an access token or special headers, or utility functions to communicate with
AsyncStorage on mobile or
localStorage on web.
This is where all of my Redux Action Creators go, I may choose to nest a folder called
async in this directory to specify asynchronous actions. For async actions I use the standard method which is via the
navigation directory is where I put my
react-router (on web) or
react-navigation (on mobile) specifications. I usually integrate my navigation with Redux.
static directory is where I put my static assets, this could be icons, fonts, images etc. I usually nest folders within this directory depending on how my application is organized.
Although I may define stylesheets within presentational components, I usually like keeping my styles in one place within the
hocs directory (optional)
If I notice that frontend application logic may be repetitive across multiple components I may choose to create a Higher Order Component. The files in this directory are named
withFunctionalityName.js where FunctionalityName is the name of what the HOC adds to the component.
api directory (optional)
I may also choose to isolate all of the async requests that communicate to an API in their own
There are definitely a lot of ways to scaffold a React based application but choosing and defining a standard way and sticking to it can go a long way in ensuring that code stays organized and easy to maintain. If you have any suggestions or comments in regards to how you scaffold your own projects feel free to comment below.