This post summarizes my tech talk at Stanford ACM on Nov 16, 2015.

React is a simple and useful library with a growing community, and we love it. But a consequence of Facebook’s hands-off approach for convention is that the community doesn’t agree on the best way to use it, especially when it comes to combining components together in a scalable way (aka architecture). There are 15+ architectures that implement Facebook’s Flux pattern, and even more that don’t. In a front-end world filled with framework FOMO, where do you start?

At Zugata, we spent a month comparing different libraries, architectures, and styles for programming in React, even forking 8 different starter kits for the initial product. We tried and nixed featureful frameworks like Reapp, inline-CSS design frameworks like Material UI, straight-up HTML5 Canvas rendering using Flipboard’s react-canvas, and more.

The criteria used to compare the stacks included the following, in order of importance:

1. The “new-engineer heuristic”

This is my way of saying that a new, intelligent, and decently-experienced engineer should have minimal difficulty finding where an existing particular piece of code is, and finding where to add a new piece of code. Grepping for function names, code dependencies in unintuitive places, and needing to duplicate CSS variables in JavaScript are all anti-patterns and fail the heuristic.

Eventually, we settled on a system that minimizes the errors a new engineer could make. Instead of making a crazy and untraceable nest of event listeners and data dependencies, we liked Flux’s approach to a unidirectional data flow, stemming from App.jsx and data stores and terminating with the simplest DOM nodes. For styling, we group LESS styles with React components, using the same name for classes as the corresponding React component and nesting small child components’ styles under their parent’s CSS class. This makes finding styles for components trivial. We also group all JSX code in various render methods (that start with the word “render”) at the bottom of each component. This eliminates the unpredictability of having angle brackets all over component code, makes CSS styling easier and quicker, eases the act of breaking off child DOM elements into separate components, and helps us create Dumb and Smart components. Speaking of which…

2. Separating Dumb components from Smart components

Explained here by Dan Abramov, Dumb components are basically very reusable components that have minimal Flux dependencies and are stateless, using only props and context. Smart components usually maintain state and respond to Flux stores and actions. To maximize code reuse and decomposition, we created a directory of “elements”, a directory of “widgets”, and a directory of “pages”. Pages are smart components that React Router maps to a route. Widgets are Smart components that aren’t mapped to routes, and they’re often reused across multiple pages and widgets. And Elements are Dumb components that are reused very frequently, use minimal CSS styles, and could easily be dropped into another React project.

3. Self-perpetuating code safety

In practice, a startup can’t write tests for every single aspect of the front-end (the API is a different story). So an important part of a JavaScript project’s architecture is being “automatically safe” about the way code gets written. Examples of this that we settled on are React PropType-checking that accompanies most components (especially Elements), using ES6 const as much as possible to avoid unintentional reassignment, and functions that use single destructured objects as a parameter to allow parameter naming. This pattern has a lot in common with the “new-engineer heuristic”: current engineers should be forced to write safe code that forces new engineers to also write safe code. The cycle should be as self-enforcing as possible.

The result

We settled on a stack in March 2015 that uses Webpack, Gulp, React Hot Loader, Reflux, Babel, Materialize, and LESS, and we’ve been building out app.zugata.com with it ever since. (We went with LESS over SCSS because of variable scoping, and we preferred it to JavaScript-based inline styles because @media queries are a fast and easy to write when making components responsive.)

Getting started is the hardest part. To help, I put together a starter kit that mimics our architecture and presented it during the tech talk I gave for Stanford ACM. You can use it to visualize your coworkers’ activity on Slack (screenshot below).

You can also see the interactive presentation I made about React (made in React too) here.

Good luck!

Slacktivity, a sample app in react-slack-tutorial, visualizes your coworkers' activity between channels over time.

Slacktivity, a sample app in react-slack-tutorial, visualizes your coworkers' activity between channels over time.


alex

Alex Atallah
Software Engineer

 

Comment