Front-End Stack for EveryDollar

Front-End Stack for EveryDollar

Over the past year, I’ve been working on the EveryDollar.com online budgeting tool with a group of talented developers. EveryDollar is a Single Page Application (SPA) developed with Facebook’s React library using ECMAScript 2015 (aka ES6), the next version of JavaScript. This blog post uncovers the tools and technologies we use to create the Front-End of EveryDollar.

High Level Architecture

Integration

From a high level, The EveryDollar.com web Front-End communicates to a RESTful hypermedia service layer using AJAX and CORS. The same service layer is also used by our native iOS EveryDollar app.

ECMAScript 2015

On the web, we decided to use Facebook’s React library because we liked its declarative and composable nature, we appreciated the simplicity of its one-way data flow, and we wanted something that could easily scale to accommodate our users. We also wanted to leverage the latest version of JavaScript so we started to use Babel to compile ECMAScript 2015 (ES6) to ECMAScript 5 (ES5). The following is a trivial example using some new features from ES6.

npm install babel

CommonJS Modules

We also decided to use CommonJS modules to organize our application. This enables us to better define dependencies between our components and also enables us to leverage other modules from the ever-growing npm community. Currently we use Browserify to allow us to require CommonJS modules in the browser, but we are also currently evaluating Webpack as an alternative. The following shows how we can use just one method from lodash and leverage it in our code.

jQuery-free

This may surprise some, but we don’t use jQuery in our application. React provides a nice level of abstraction that removes our need for jQuery. At some point we may need to integrate with a third-party jQuery plugin or widget, but thus far we have either . . .

  • Developed our own React components or vanilla JS libraries
  • Found other npm open source React components or vanilla JS libraries

Supported Browsers

For our web application, we decided to only support modern browsers, which for us translates to IE10+ and other browsers. Yes, IE9 is much better than IE8, but once you raise the bar to IE10 it enables many more features such as CSS Animations, CSS flexbox, matchMedia, ES5 strict mode, and much more.

One of the really cool things that I’ve noticed over the past year is that I rarely have to think about Internet Explorer, because things just work! We occasionally have to polyfill some features, but that is few and far between.

Statistics

So far our application has over 270 React components, over 7,000 lines of source code, and over 700 Jasmine unit tests.

# Number of React Components
find src/ -name "*.jsx" -print | grep -v __tests__ | wc -l
 
# Lines of Code
npm install -g sloc
sloc src/

Other JavaScript Libraries

Unlike other frameworks like Angular or Ember, React doesn’t provide all of the components that you might need for a full-fledged Single Page Application. So, you’ll find yourself augmenting React with a handful of micro-libraries.

Routing

For our routing library, we are currently using director. We are actually currently doing a tech spike to switch from director to React Router by Ryan Florance and Michael Jackson. Ryan and Michael have been very active in the community and have worked closely with Facebook to make sure their direction matches where the technology is moving.

npm install director
npm install react-router

Ajax

For AJAX we are using the reqwest micro-library by Dustin Diaz. The API for reqwest is very similar to jQuery’s $.ajax method, which is both familiar to us and very easy to use. The following is a simple example of what the API looks like.

npm install reqwest

Flux

React can be thought of as the V in MVC, which means that it doesn’t concern itself with much else other than the view portion of the application. So, in order to bring structure to our application we use the reflux library, which is a simple unidirectional dataflow architecture inspired by React’s Flux Pattern.

npm install reflux

Immutability

React does a great job of being attentive to performance by only updating the DOM when it’s necessary. One way that we can help React to be more efficient is to use Immutable collections for JavaScript using Lee Byron’s Immutable.js library.

npm install immutable

Internationalization

Even though we currently only support English, we use FormatJS which is a library for internationalization. The library provides React Components and a Mixin to format numbers, dates/times, relative times, and complex messages using the ICU Message syntax.

npm install react-intl

Validation

Client-side validation is an important usability concern that needs to be accounted for. For our validation, we ended up wrapping the joi library, which is an object schema description language for validating JavaScript objects. For example, the following code validates that an object requires the name and age properties.

npm install joi

CSS

CSS is an important part of a web application and managing styles in a large codebase is important for maintainability. We leverage several tools and technologies to help us organize our styles, enforce standards, and support cross-browser features.

Sass

We use the Sass preprocessor to help us organize our styles into separate partials (_partial.scss) using the @import rule, leverage variables to share common data, use @mixins to group common CSS declarations, and use @extend to allow properties to be shared across several selectors. The following is an example of some of the things you can do with Sass.

BEM

In addition to using Sass, we use the BEM naming convention as we author our selectors. We have varied from the official rules somewhat and use A BEM syntax with UX in mind. The following is an example of our naming convention.

SCUT

Something that I’ve used in other projects and we plan to add to EveryDollar is Sass-CSS Utilities (SCUT). It has a lot of handy utilities that make CSS more terse and convenient. The following is an example of some handy scut mixins (scut-padding, scut-size, scut-margin, scut-center-transform, and scut-absolute) and the resulting CSS.

SCSS Source

CSS Output

AutoPrefixer

We use a post-processor tool called Autoprefixer that enables us to write all of our CSS rules without vendor prefixes. We run the tool as part of our build system and it parses our CSS and adds any necessary vendor prefixes using values from Can I Use. The following is an example of a standard CSS declaration and the corresponding CSS output after Autoprefixer has been executed.

SCSS Source

CSS Output

Code Quality

Code quality is very important to us. As our application grows, both in size and development effort, it is key to have a set of quality checks and balances in place. To keep our project on the right path, we incorporate static analysis, testing, and peer reviews to keep our application healthy.

Static Analysis

Call me strange, but I really enjoy static analysis. Once a team has agreed on how things should work, I like being able to enforce that set of rules if at all possible. We have found three such tools to be handy in our project.

  1. JSHint helps us enforce best practices in JavaScript. The following are some settings that I find really helpful. As a side note, we are currently looking to replace JSHint with ESLint. ESLint has all the same features as JSHint, but you can create your own custom rules or leverage those created by the community.
  2. JSCS helps enforce coding style. You can start with a preset of rules and then tweak the rules to suit your application.
  3. SCSS-Lint helps bring static analysis to our Sass code. The following are some of my favorite rules to help enforce consistency and maintainability in our Sass.

Testing

In addition to static analysis, we try to add a level of unit testing and integration testing to the EveryDollar Front-End. We use Jasmine as our testing library and find it well suited for our needs.

We have our tests integrated into our GitHub Pull Request workflow with Travis. The great things about Travis integration is that unit test and lint checks are performed even before a peer developer reviews the code. This allows the reviewer to focus on higher concerns such as what the code does and how it is architected.

Peer Reviews

We host our code on GitHub, and when we are ready to merge our code to master, we first create a Pull Request so that another Front-End developer can peer review the code. We find this Pull Request process is important for several reasons:

  1. They enable other developers to make comments on how a particular feature was developed. Maybe there is a technique the developer wasn’t aware of or maybe there is a utility method already available that could have been a good fit.
  2. They are a good way to communicate new features or techniques to other developers on the team.
  3. They give opportunities for seasoned developers to train junior or mid-level developers.
  4. They encourage focused work on one particular task instead of making a bunch of unrelated changes.
  5. They open up the opportunity to cheer other developers on their awesome work.

Summary

I hope now you have a somewhat better understanding of how the EveryDollar Front-End is composed. The above is really only scratching the surface. There is a lot more to EveryDollar and we are adding to it all the time. Thank you for your interest, and if you haven’t already tried EveryDollar, now is the time!

By the way, we are hiring lots of developers at Ramsey Solutions, and we even have some job openings on the EveryDollar team.

  • http://williamedmondson.com William Edmondson

    I am interested in the discussions you had around choosing browser support. It can be scary to say you are purposefully ignoring a certain portion of your potential customer base. Most larger organisations don’t have the will to make that decision.nnnWas this difficult decision for your team? Have you seen any kind of push back from customers?

    • http://blog.eldergoth.com/ carson63000

      If Elijah’s analytics look anything like mine, it wouldn’t have been a difficult decision. I just checked out last three months of sales and pre-IE10 versions of IE accounted for a little over 1% of our total IE revenue (this is on a site where we make an effort to support IE8+).

  • designaroni

    Very good layout of the stack, not too in depth but I find that okay. I’m always interested to hear about the stack used by developers & the front end solutions they choose to use. We need more open discussion of the tools & processes in the Front End community.

© 2017 Lampo Licensing, LLC. All rights reserved.

www.daveramsey.com