React Native App Stack, March 2017
This week, we started writing a new React Native app at Formidable. With every new project, I experience a mix of giddy excitement and intense anxiety: an opportunity to right all past mistakes, and a chance to make a thousand new ones.
Discussing greenfield tech choices inevitably devolves into bikeshedding. “Uhh, so which async redux middleware should we use?” is an incredibly common time-sink, and at the end of the day, probably not the choice that will decide the success or the failure of your software product.
That’s why a year ago I wrote Pepperoni, a React Native boilerplate to end bikeshedding once and for all. Except, of course, it didn’t end. In the year since, everything’s changed!
I still believe that boilerplates are useful to ramp up new projects quickly, but not to enforce library choices. There’s no one-size-fits-all solution.
Instead, I wanted to share our latest choices as a list, and give shout-outs to the most important new tools and developments of the last year. (Meanwhile, many of these new tools have been added to Pepperoni by the active contributor community.)
- React Native (duh)
- Redux architecture following the Ducks pattern
- redux-observable for side effects
- redux-persist for offline caching
- react-navigation for navigation
- styled-components for UI styling
- Yarn for dependency management
- Flow for static type checking
- Jest and Enzyme for testing
- Prettier for code formatting
- Storybook for component style guide
When I started writing this post, I didn’t realize what is now plain to see: Except for Redux, none of these tools were part of my toolkit one year ago.
👏 react-navigation, though still in its early days, solves the previously lackluster navigation story beautifully, and works well with Redux.
👏 styled-components, while strictly speaking mostly a syntactic improvement over the standard React Native styling, encourages small presentational components and more considered design systems in UI development.
👏 redux-observable is our answer to the question: “which async redux middleware should we use?”. It’s expressive enough to solve asynchrony and effects modelling without introducing accidental complexity (I’m looking at you, sagas), and the underlying RxJS 5 is faster and tighter than it’s predecessor. I have only begun to use redux-observable, but I already love it. (For full disclosure, our budding love story is something of a rebound: my previous partner, 👻redux-loop, is going through a rewrite, and we needed some time apart to see if we still want to be together.)
Surprisingly missing from this list is 👻Immutable.js. While a great library, its bespoke collections API introduces too many challenges in interfacing with third-party code and serialization boundaries. If I feel we need development-time mutation-safety, I’ll reach for 👏 seamless-immutable, but for now we’re going with pure willpower, and static typing.
On the tooling side, Facebook Open Source is putting out amazing work beyond Flow. 👏 Yarn is a no-brainer. Faster, reproducible dependency management? Yes, please. 👏 Jest has seen massive improvements in the last year and is now the simplest React test runner out there. The jury is still out on the long-term effects of snapshot testing on codebase maintainability, so we still use AirBnB’s 👏 Enzyme for writing BDD-style UI test assertions.
Code style arguments used to be a big source of bikeshedding, but there’s no point arguing against the 👏 Prettier code formatter. The computer will always win, and it does not care about your feelings. We still use ESLint to supplement.
Finally, I can’t leave out React Native 👏 Storybook. A long-time best practice in web development, style guide -driven design systems haven’t traditionally reached ubiquity in mobile development, perhaps because of the underpowered component systems in native SDKs. With React Native (and styled-components) there are no excuses not to build interactive pattern libraries on mobile. At Formidable, we take style guides seriously.
(You might ask, where’s Apollo or Relay? Or reselect and normalizr. All great tools, but I see using them as a per-project choices to solve specific problems, not part of “the stack”. If you think I’ve missed something crucial, let me know in the comments.)
This link dump represents my team’s best ideas on how to build mobile apps with React Native in March 2017. I look forward to reviewing this list in a year, and marvelling at how far we’ll have come again.
Here’s a few more 👏👏👏 for all the amazing people in the open source community, creating libraries and tools, without which we’d have nothing.
And remember, there is much more to building great software than choosing your tools. Once chosen, they must be wielded with great precision and applied to a good cause: to create apps your users love, and your future self can look back to and feel a twinge of pride among the inevitable “I can’t believe we used to do it like THAT back then”.