A Simple React + Redux Starter Kit

Ryan Irilli
Points San Francisco
10 min readJun 27, 2016

For the impatient, Skip the explanation and go straight to the code

You’re a front end engineer with an entrepreneurial spirit. You woke up in the middle of the night with a rush of inspiration. You have an idea that just may be the most genius concept ever and you want to get something up and running quick. But before you can get started on the actual product, there’s a bunch of boilerplate work to get your application ready for the real work you’re trying to do.

It can be a huge buzz kill to set all this up, take it from me. You may find yourself over it before even getting started, or you may find that the tools you chose to use have you down a rabbit hole of incomprehensible errors. Or, you already found a boilerplate project but it too contains way more libraries than you need to get a simple project off the ground.

This is why I developed this boilerplate, because the story above was me not too long ago. There was no straight forward path to getting a project up and running that I could analyze and understand. I knew how each component of a build system worked (more or less) but there were not many projects that combined these tools to work in concert and provide a simple starting point.

One thing to note is I am a HUGE Ember-cli fan and have been for years. I love how that project provides a fully developed build system and, assuming you understand the nature of the Ember framework, you can hit the ground running writing your app instead of configuring the tooling.

So Without further ado, I’d like to introduce and give you a tour of my React JSPM Starter Kit project.

Overview

Now, you’ll notice I mention React and JSPM. There are actually a handful of open source projects I use in the starter kit, but I didn’t want to scare anyone off so I chose only the two that are the biggest differentiator in my project from the hundreds of other boilerplate repos out there.

First, React is the primary tool in building your front end. I do not have enough time in this post to explain exactly how it works, so if you’re not familiar with it (or Redux), the I suggest starting on the React homepage and going through these videos by Dan Abramov, the mastermind behind Redux. TRUST ME! you will be up and running in no time and the concepts are guaranteed to change the way you think about modern web development. I will also be going over each concept of the boilerplate in this post so you should also just keep reading.

Secondly, JSPM stands for Javascript Package Manager and is being developed by Guy Bedford. If you have seen other React/REDUX boilerplate projects before you will likely notice they are using Webpack to manage the build and transpilation of your source code into something a browser can load, JSPM essentially manages the same thing. Again, I do not have enough time to explain the ins and outs here, but it is phenomenal for two basic reasons. 1. You can install dependencies super easy with a single install cmd and 2. you can then go right into your project and import that dependency. there is virtually no manual configuration needed because it is automatically handled for you and you get to use ES6 (via Babel) right out of the box, again, no configuration! At the time of making this project Webpack did not offer something as simple and so I chose JSPM instead (and I have no regrets).

Getting Started

Okay, enough talk, let’s dive into some code and I will walk you through how it works. I am going to cover these three topics:

  • Install and starting your local server
  • Testing your application
  • Bundling your application for production

There’s a lot more I could cover but let’s just stick to the basics for this post. Okay here we go.

First, follow the steps in the README of the repo linked below

At this point, you should have all the dependencies installed and ready to start your local server for development. This project uses Gulp for automating tasks so the first thing to note is the available commands will be printed if you simply type

gulpgulp serve //serves your app locally
gulp serve -- prod //serves the production build of your app locally
gulp build //bundles your app for production
gulp test //runs your tests using Phantomjs
gulp test -- debug //runs your tests using Chrome

That’s it, plain and simple. typing the “gulp serve” command kicks you off with a development server and all you need to do is point your browser to http://localhost:8080. You are now up and running and ready to work on your app. Behind the scenes, there are also watch tasks running so when .js, .jsx, or .scss files change, your browser will automatically reload to reflect those changes.

The Architecture

Okay, I know I said I wouldn’t go into all this but I think it’s important for you (and for me) to explain the setup in more detail. First of all, Everything starts with the index file

/src/index.js

Here we import everything needed to initialize a React/Redux application including defining the routes of our application

index.js

There is a lot going on in these 28 lines of code but it can be made clear by reading the basic ideas in these four projects: redux, react-redux, react-router, react-router-redux. If you spend a few minutes with each of them and return to the image above, it should make things a lot more clear.

The next concept to highlight is the idea of “connected” components. As you can see, we have only one Component in this starter kit and it’s called AppContainer which looks like this

App.jsx

This is what we call a Connected Component because these types of components connect your React Component (App) with the state of your application using two functions `mapStateToProps` and `mapDispatchToProps`.

mapStateToProps - returns an object where the keys are the properties that will be available to the component via this.propsfor example:function mapStateToProps(state) {
return {
firstName: state.user.get('firstName')
}
}
//App.jsx
...
componentWillMount() {
console.log(this.props.firstName);
}
...mapDispatchToProps - returns an object where the keys are namespaces for action creators that the component uses to pass user entered data to your system to set on the application state and/or used to make API calls to your backend for example: function fetchUser(userId) {
return dispatch => {
Api.fetchUser(userId).then(user => dispatch({
type: 'SET_USER',
user
}))
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({
fetchCurrentUser: fetchUser
}, dispatch);
}
//App.jsx
...
componentWillMount() {
console.log(this.props.fetchCurrentUser('1234'));
}
...

If you feel like you understand these concepts then you are ready to move forward using my starter kit, if not, don’t worry! It definitely did NOT click for me right away, it took some time. Dan explains the concepts I just went over in much better detail in this post. I will point out, for testing purposes, it’s crucial you do not nest connected components, You would not want to import some OtherContainerComponent and use it in App

WRONGexport const App = React.createClass({
render() {
return <div>
<OtherContainerComponent />
</div>
}
});

The reason you cannot do this is because when testing we do not use the container components at all, we import the basic react component and pass in mock data and functions, including action creators. This is the beauty of this architecture is testing becomes trivial! The better way to compose all these smart components is simply through your Route hierarchy or by passing props from your connected components down to basic “Presentational” components. Again, I will point to Dan’s post on the subject

RIGHT<Route path="/" component={AppContainer}> 
<Route path="/" component={OtherContainer}>
</Route>

Testing your app

Okay, I have no clue how you’re still with me here but I am really glad you are. If you’ve been a front end developer for some time then you know testing the front end is a relatively new requirement for us (we used to get by just by clicking around in browsers and giving a thumbs up) but now of days it’s absolutely vital to test your code for these single page apps (after all they are consuming quite a bit more domain logic than ever before)

Luckily, I have you covered with a dead simple testing setup using Karma, Mocha, Sinon and Chai. For the sake of not driving you insane, I am going to scope this section to only showing you how to test a component. I could absolutely go into testing action creators and reducers but honestly, my fingers are starting to cramp. Once you understand how the nature of testing works, you will EASILY be able to write tests for the other layers of your app (and we do at my company, Points)

Remember App.jsx (the only component in the starter kit), it looks like this

export const App = React.createClass({
render() {
return <div className="app-container">
<img ref="unsulliedLogo"
alt="unsullied logo"
className="unsullied-logo"
src="/static/img/unsullied-logo.svg" />
</div>
}
});

...
export const AppContainer = connect(mapStateToProps, mapDispatchToProps)(App);

Notice we have two exports, one is the connected component and the other is the basic React component. In testing, we do want to have the component connected to any kind of store, we simple want to create an instance of the component and pass in the state of our application via props (again, this is the beauty of this architecture!)

So a simple test looks like this

import React from 'react';
import { renderIntoDocument } from 'react-addons-test-utils';
import { App } from './../src/components/App.jsx!'

function createComponent(props = {}) {
return renderIntoDocument( <App />);
}

context('App', () => {
it('should have a logo img ', () => {
const AppComponent = createComponent();
const src = AppComponent.refs.unsulliedLogo.getAttribute('src')
expect(src).to.equal('/static/img/unsullied-logo.svg');
})
});

Now let’s say the App component uses the User data to display their first name (maybe in the top nav or something) In your Application you would get this data by fetching it via AJAX and dispatching an action with the returned data (and connecting it to the App component via mapStateToProps) but in a test environment we don’t need all that nonsense, so we do it like this

import React from 'react';
import { renderIntoDocument } from 'react-addons-test-utils';
import { App } from './../src/components/App.jsx!'

function createComponent(props = {}) {
return renderIntoDocument( <App user={props.user} />);
}

context('App', () => {
it('should render the users first name', () => {
const props = { user: {firstName: 'Ryan'} };
const AppComponent = createComponent(props);
expect(AppComponent.refs.name.textContent).to.equal('Ryan');
})
});

So awesome, And action creators work in a very similar way. If you have some action that you pass into your component via `mapDispatchToProps`, you can use Sinon’s spy functionality to verify they get called and with the appropriate arguments. For example

import React from 'react';
import { renderIntoDocument } from 'react-addons-test-utils';
import { App } from './../src/components/App.jsx!'

function createComponent(props = {}) {
return renderIntoDocument( <App user={props.user} />);
}

context('App', () => {
it('should render the users first name', () => {
const fetchUser = sinon.spy();
const props = { fetchUser };
const AppComponent = createComponent(props);
expect(fetchUser.calledWithExactly('1234')).to.be.true;
})
});

Hopefully this is starting to click for you and you can see just how easy it is to divorce the state and data from your application from the testing environment. stubbed actions and mock data can “feed” your instances to cause the code you are testing to be executed.

Bundling For Production

And finally, bringing it all together. Once you have that amazing idea fully implemented and realized, it is time to bundle your app for production. Luckily, this needs the least amount of explanation because it is very straight forward. All you do is run

gulp build

This kicks off a handful of tasks. First it compiles all the fancy ES6 and JSX code into browser friendly javascript. Next, it concatenates all that into a single file (app.js) and finally it revisions the file so when you deploy, the browser knows not to use some cached version of your app but to download the latest code. The same flow happens for your SCSS to generate a css file. I know we haven’t talked much about CSS but the short version is I use SCSS and feel strongly that you should too. It also copies all your images and fonts into a single directory. In the end, you get a build directory that looks something like this

Build directory output after running gulp build

that index.html file is what you’ll end up serving to your users and everything should just work.

Finally I’d like to point out you can modify naming conventions of this build system at the top of the gulpfile.js

build configuration in gulpfile.js

Heck, have a thorough look at this gulpfile, it’s incredibly simple to understand and the idea is that you can really go in and get your hands dirty with the build system easily. Remember when I said I use SCSS and you should too and you rolled your eyes? Well get in there and rip that nonsense out! This is your build system now and you can and should do whatever makes you happy and a more efficient developer. Remember, the goal here is to get all this out of the way so you can spend more time building your app and less time architecting.

Conclusion

And so here we are, you somehow made it to the end. All I can say is this project was conceived and developed with love for the game. I love building front end applications, great user experiences, and beautiful design. By offering this project to the world I hope you can more easily experiment and build prototypes faster. Please feel free to reach out to me with ways we can improve this project, I am always open to having real life discussions about improving it or making things more clear. Good luck and keep on rockin’ in the free world.

--

--

Ryan Irilli
Points San Francisco

Web developer. React nerd. Design and code tinkererer.