---
title: Announcing Purple Train
teaser: We shipped a mobile app that efficiently shows MBTA Commuter Rail departure
  times.
tags: news,ios,android,react native,elm,mobile
author: Ian C. Anderson
published_on: 2017-01-09
---

I've always wanted to ship an iOS app, and I'm happy to report that this is the
year that I've finally done it (with help from many of my coworkers, I should
say!). That app is [Purple Train].

![Purple Train screenshot](https://images.thoughtbot.com/ia-announcing-purple-train/TujwAPQD6B8G2RoVixXA_purple-train-iphone-app-f7b427aaec509ee65069d07f2e809152.png)

## The problem

Purple Train is an answer to a simple question: when do the next MBTA Commuter
Rail trains (that I care about) depart? I had tried a few other apps that show
this information, but not in an efficient way. I wanted something that I could
very quickly open, refer to, and get back to my day.

## The solution

By assuming that you commute to Boston from your single "home" train stop,
the app offers an easy and efficient interface: choose your home stop, and
immediately see the trains that go to and from Boston. If there are express
trains that don't stop at your home stop, they are automatically filtered out,
keeping the interface free of distracting noise.

## The technology

### Frontend

Before I started working on the app, I heard some compelling reasons to use
React Native, so I installed it and gave it a try. I wasn't excited about the
idea of writing the app in JavaScript, but I was intrigued by the opportunity
for [cross-platform development], and I was already familiar with the functional
reactive paradigm offered by React and Redux. After being surprised by how
productive I could be in React Native, I decided to use it for Purple Train.

[Cole Townsend] worked on the initial designs for the app, and he felt quite
comfortable implementing them with React Native's [StyleSheet] support.

After the basic functionality worked on iOS, [Justin Kenyon] and I spent a
half day to get the app working on Android. We were thrilled with how easy this
process was. In the end, our application had no platform-specific code; all of
that work was abstracted away from us via React Native and a few third party
libraries.

Thanks to [Blake Williams], [Justin Kenyon], [Derek Prior], and [Mike Borsare]
for working on the frontend code!

### Backend

The backend for the app is an Elixir Phoenix application that caches responses
from the [MBTA's Realtime API] and serves the mobile app with small JSON
payloads that are tailored to the user's home stop.

The Phoenix app uses the [Agent] module provided by Elixir to store the cached
API responses from the MBTA. This gives us a lightning-fast in-memory store that
helps the backend respond with data right away.

There is some logic on the backend that filters out any trips that the user
doesn't care about (such as trips that have already left the user's station or
express trains that don't go to the user's home stop). This makes the job of the
frontend easier and keeps the JSON responses small, which is important for
mobile performance.

Thanks to [Derek Prior] and [Josh Clayton] for their help with writing (and
re-writing) the backend!

## Takeaways

Developers and designers that are used to building for the web can be productive
right away with React Native. The language is familiar (JavaScript), the
workflow is familiar (Cmd+R or live reloading in the simulators), and the
concepts are familiar (functional reactive programming, style sheets).

This familiarity, and the productivity gains it provides, makes React Native a
compelling option for many multi-platform mobile apps, despite the pitfalls from
using JavaScript.

## Elm Native

We like the workflow, we like the concepts, and we're familiar with the
language, but we miss some of the safety and ease of refactoring that we get
from "native" compiled languages like Swift and Kotlin.

How can we get the productive workflow without running into JavaScript errors
like `undefined is not a function`? Wouldn't it be cool if we could use the
[Elm] language so we could feel more confident that our code is correct?

Luckily, the simplicity of the Purple Train app makes it a good testbed to try
experimental technologies. Stay tuned for a post about our experience porting
Purple Train to [Elm] using [elm-native-ui]!

## Related

- Read [Rapid cross-platform mobile development with React Native]
- Listen to the [Bikeshed Podcast episode] about Purple Train

[Agent]: http://elixir-lang.org/getting-started/mix-otp/agent.html
[Bikeshed Podcast episode]: http://bikeshed.fm/86
[Blake Williams]: https://twitter.com/blakewilliams__
[Cole Townsend]: https://twitter.com/twnsndco
[Derek Prior]: https://twitter.com/derekprior
[Elm]: http://elm-lang.org
[Josh Clayton]: https://twitter.com/joshuaclayton
[Justin Kenyon]: https://twitter.com/kenyonj
[Mike Borsare]: https://twitter.com/mborsare
[MBTA's Realtime API]: http://realtime.mbta.com/portal
[Purple Train]: https://apps.apple.com/us/app/purple-train/id1153352657
[Rapid cross-platform mobile development with React Native]: https://thoughtbot.com/blog/rapid-cross-platform-mobile-development-with-react-native
[StyleSheet]: https://facebook.github.io/react-native/docs/stylesheet.html
[cross-platform development]: https://thoughtbot.com/blog/rapid-cross-platform-mobile-development-with-react-native
[elm-native-ui]: https://github.com/ohanhi/elm-native-ui
