Ignite IR Boilerplate ("Bowser")
NOTE: This repo has been renamed from ignite-ir-boilerplate-bowser to ignite-bowser. Although web traffic and git operations for the previous name will be redirected, we recommend you update any links and git urls for this repo.
Infinite Red's latest and greatest React Native boilerplate
Once you've installed the Ignite CLI, you can get started with this boilerplate.
- React Native
- React Navigation
- MobX State Tree (Why MST?)
- Reactotron (requires 2.x)
- And more!
To see it in action, check out the Chain React 2019 Conference App!
First, install Ignite CLI:
$ yarn global add ignite-cli
Then spin up a new Bowser-powered React Native app:
$ ignite new MyApp -b bowser
The Ignite Bowser boilerplate project's structure will look similar to this:
ignite-project ├── app │ ├── components │ ├── i18n │ ├── models │ ├── navigation │ ├── screens │ ├── services │ ├── theme │ ├── utils │ ├── app.tsx │ ├── environment-variables.ts ├── storybook │ ├── views │ ├── index.ts │ ├── storybook-registry.ts │ ├── storybook.ts ├── test │ ├── __snapshots__ │ ├── storyshots.test.ts.snap │ ├── mock-i18n.ts │ ├── mock-reactotron.ts │ ├── setup.ts │ ├── storyshots.test.ts ├── README.md ├── android ├── ignite │ ├── ignite.json │ └── plugins ├── index.js ├── ios └── package.json
Included in an Ignite boilerplate project is the
app directory. This is a directory you would normally have to create when using vanilla React Native.
The inside of the
app directory looks similar to the following:
app │── components │── i18n ├── models ├── navigation ├── screens ├── services ├── theme ├── utils ├── app.tsx ├── environment-variables.ts
This is where your React dumb components will live. Each component will have a directory containing the
.tsx file, along with a story file, and optionally
.props files for larger components. The app will come with some commonly used components like Button.
This is where your translations will live if you are using
This is where your app's models will live. Each model has a directory which will contain the
mobx-state-tree model file, test file, and any other supporting files like actions, types, etc. There's also an extensions directory with useful shared extensions that you can include in your models like
.extend(withEnvironment) to access the root store or environment respectively.
This is where your
react-navigation navigators will live.
This is where your screen components will live. A screen is a React component which will take up the entire screen and be part of the navigation hierarchy. Each screen will have a directory containing the
.tsx file, along with any assets or other helper files.
services Any services that interface with the outside world will live here (think REST APIs, Push Notifications, etc.).
theme Here lives the theme for your application, including spacing, colors, and typography.
utils This is a great place to put miscellaneous helpers and utilities. Things like date helpers, formatters, etc. are often found here. However, it should only be used for things that are truely shared across your application. If a helper or utility is only used by a specific component or model, consider co-locating your helper with that component or model.
app.tsx This is the entry point to your app. This is where you will find the main App component which renders the rest of the application. This is also where you will specify whether you want to run the app in storybook mode.
ignite directory stores all things Ignite, including CLI and boilerplate items. Here you will find generators, plugins and examples to help you get started with React Native.
This is where your stories will be registered and where the Storybook configs will live
This directory will hold your Jest configs and mocks, as well as your storyshots test file. This is a file that contains the snapshots of all your component storybooks.
About The Stack
Why this stack?
If you've used Ignite Andross (the first Ignite stack), you know we formerly used Redux for state management, as does much of the community. However, we encountered some pain points with Redux so went in search of a different solution to meet our needs and landed on
mobx-state-tree. We find that it’s a great middle ground between completely structured (like
redux) and completely freestyle (like
mobx). It brings more than just state-management to the table as well (such as dependency injection, serialization, and lifecycle events).
Some Highlights of MST
- With concepts like
actions, it feels familiar for React developers
- Updating your data means calling functions on objects, rather than dispatching actions.
- Feels similar to relational databases, with concepts like
references(foreign keys), and
- With concepts like
- No more
- You don't have to declare your usage intentions with
mapStateToProps; they are inferred
- Side-effects are built in; no need for 3rd party libraries like
- Immutability is built-in - no need for
model.extendallow for easy code-sharing of common patterns
- No more
- More than state management
- Lifecycle hooks like
beforeDestroylet you have control over your data at various points in its lifecycle
- Dependency injection with
getEnvallows you to reference your environment (like API or other services)
- Lifecycle hooks like
- Round-trip store writes are much faster
- Computed values (views) are only calculated when needed
mobx-reactmakes React "MobX-aware" and only re-renders when absolutely necessary
- MST ships with pre-built middlewares, including one which allows for Redux interoperability. These middlewares can also serve as examples to create your own!
We also recognize no state management solution is perfect. MST has some known downfalls:
- Integration with TypeScript is clunky at times. MST's own typing system is sometimes at odds with what TypeScript wants
mobx-state-treeboth seem to have "magic" or "sorcery" that makes issues less straightforward to debug because you don't always have a clear picture of what's happening (but using Reactotron, which has
mobx-state-treesupport built-in, helps a lot). The MobX docs can also help illumitate some of the magic.
- The user base is small, so finding help on GitHub or Stack overflow is less convenient (however, the Infinite Red Slack Community, as well as the MobX State Tree Spectrum channel are both very helpful)
- Fatal errors are sometimes too-easily triggered and error messages can be verbose and hard to grok
- The API has a large surface area and the docs tend to be technical and unfriendly
Learning MobX State Tree
MobX and MobX State Tree can be a lot to learn if you're coming from Redux, so here are a few of our favorite resources to learn the basics:
Be sure to check out the official Getting Started guide for MobX State Tree.
There is also a free egghead.io course.
For a great explanation and walkthrough of the basics, check out State Management with MobX State Tree by React Native Training.
And for more in-depth reading, the official documentation is a great resource.
The official docs for MobX are another important resource, since MST is built on MobX.
To see example code bases using Bowser (and MST), check out these two:
https://github.com/jamonholmgren/PlayerPopularity (simple implementation)
https://github.com/infinitered/ChainReactApp2019 (more in-depth implementation)
To keep your React Native app updated:
To keep your Ignite Bowser based app updated:
- ignite-bowser-difff-purge To help you see the diffs between versions
In addition to
mobx-state-tree, we've also transitioned to using
TypeScript vs plain
In Bowser, TypeScript is fully set up, so if you know TS, all you need to do is start coding!
If you are new to TypeScript, here are some of our favorite resources:
- TypeScript in 5 minutes for a quick read
- TypeScript in 50 minutes for a longer watch
- TypeScript and VSCode for awesome developer tools
- Official Docs
Ignite CLI, Ignite Andross, and Ignite Bowser, as open source projects, are free to use and always will be. Infinite Red offers premium Ignite CLI support and general mobile app design/development services. Email us at firstname.lastname@example.org to get in touch with us for more details.