Skate

June 10, 2026 · View on GitHub

Skate is a web-based dispatch tool for bus inspectors, built by the MBTA. Imagine an app that helps you track the one bus you want to catch, but instead it’s helping us track all the buses that everyone wants to catch! It has the rich location data driving our mbta.com and rider apps, but also info that matters for keeping things running smoothly (operator names, bus numbers, shift schedules). For background, read our “Skate: Building a better bus dispatch app (and how it will improve your ride)” blog post.

Animated recording of Skate

Community

The MBTA Customer Technology Department supports a shared Slack channel that transit agencies and partners adapting the Skate code can use to collaborate and ask questions. To be invited to the Slack channel, email developer@mbta.com.

Setup

Prerequisites

Doing development on Skate requires Elixir, Erlang, and node, as described in .tool-versions. Most developers use asdf to help manage the required versions, but that isn't required.

Skate also requires Postgres. If you don't already have Postgres installed, and you're on a Mac, Postgres.app is an easy way to get started. However, any Postgres instance to which you can connect and in which you have sufficient privileges should work.

Configuring to run in a new environment

There are a number of configuration details defined in environment variables. These define where data sources live, as well as authentication and CDN details. In our AWS environments these are all set and managed via Terraform.

To avoid having to set these manually in your local development environment, direnv is strongly recommended. A .envrc.template file is provided to fill out; simply copy it over to .envrc.private and fill in the values, then follow the direnv documentation to load it.

The environment variables are documented in the Skate .envrc.template file.

Note

Some of these configuration values are shared between Skate team members. While there are still some values which are not shared and need to be configured in .envrc.private, to facilitate easier setup and to reduce the amount of work done when cloning for team members, the .envrc file is configured to source the shared configuration values from 1Password using the .env.1p.skate file and the 1Password CLI (which you must also have on your system).

Here are the values you'll need to be prepared to update to run Skate locally:

Quick Setup

First, install the project dependencies:

asdf install

Next, initialize the project:

mix setup

Important

This command will also initialize the database, so you must first ensure you have:

  1. A running Postgres instance is running
  2. Updated your credentials in .envrc.private as described in the previous section.

Note

Running mix test (as described in the testing section) will also automatically initialize the database, but you can do so manually as follows:

MIX_ENV=test mix ecto.setup

Updating

After updating merged changes or checking out a new branch (e.g. to test a new feature), you may need to do the following to update the dependencies:

  1. Update Elixir and Node.js dependencies at the same time by rerunning mix setup

OR

Update them independently with the following commands

  1. Update Elixir dependencies with mix deps.get
  2. Install Node.js dependencies with npm --prefix assets ci

Running the application

Start the Phoenix server:

mix phx.server

View the application in your browser at https://localhost:4000.

Troubleshooting

Note

If you see the "data outage" banner when you access your local deployment, it means the application could not get certain information (e.g., crowding) which can only be accessed from the MBTA network. However, most features should work locally without network access.

Tip

If you cannot access your local deployment due to SSL/TLS issues, try to regenerate the keys with:

openssl req -x509 newkey rsa:4096 \
  -keyout priv/cert/selfsigned_key.pem -out priv/cert/selfsigned.pem \
  -sha256 -days 365 -nodes -subj "/CN=localhost" -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"

You may also need to add and trust the root certificate authority in your macOS keychain.

First, add the relevant file to the keychain (you will be prompted to enter your password):

open -a 'Keychain Access' 'priv/cert/selfsigned.pem'

Finally, configure the keychain to 'Always trust' the entry named 'localhost' under the 'Certificates' tab as explained in the official Apple documentation.

Caution

You may encounter the following 'out-of-memory' error when attempting to restart the application:

literal_alloc: Cannot allocate 2628384248 bytes of memory (of type "literal").

You can resolve this issue by clearing the cached GTFS feed file:

mix cache.clean

If the issue persists, you can also increase the memory for the Erlang virtual machine to accomodate the size indicated in the error message:

# allocate 4000MB = 4GB
ERL_FLAGS="+MIscs 4000" mix phx.server

Running tests

  • Run Elixir tests with mix test
  • Run Javascript tests with npm --prefix assets test

Running Storybook

Storybook is a tool to create and test UI components in isolation. To run: npm --prefix assets run storybook

Browser Support Policy

We strive to support all users – but the variety of browsers, operating systems and devices available necessitates a more intentioned approach. These differences could potentially cause bugs and harm your experience with Skate. Ensure you have the best possible experience with Skate by updating your browser to the latest version.

Compatible Browsers

Generally speaking, Skate supports the stable latest releases of all major web browsers:

  • Chrome (version 84+)
  • Safari (version 14+)
  • Firefox (version 78+)
  • Microsoft Edge (version 84+)

Other interfaces using the underlying engines of the aforementioned browsers – that's WebKit, Blink, Gecko – are not explicitly supported but are expected to function correctly.

  • Windows 10 - Edge
  • Android - Chrome
  • MacOS / iOS - Safari

Incompatible Browsers

Skate does not work with:

  • Internet Explorer
  • Opera
  • Developer or Beta versions of supported browsers

Use of Skate on these browsers will potentially lead to bugs and a poor experience with the app. We encourage you to use one of our compatible browsers instead.

Team Conventions

Editing Code

  • Create each new feature in its own branch named with the following naming format: initials_description (for example, Jane Smith writing a search function might create a branch called JS_searchfunction)
  • Before commiting changes, format Elixir code with mix format
  • Follow Conventional Commit guidelines, by prefacing your commit message with one of the following structural elements:
    • feat: (new feature for the user)
    • fix: (bugfix)
    • chore: (a housekeeping task; no visible change to user)
    • docs: (change to documentation)
    • style: (stylistic change, e.g. formatting of text)
    • test: (only updates automated tests)
  • You can add as many commits as you'd like. If you use the "Squash & Commit" function when deploying to production, you will have the opportunity to consolidate them.

Code Review

All new features are required to be reviewed by a team member. To request a code review after checking in a new branch:

  1. Create a pull request on your new branch. Edit the description to include a link to the Asana ticket describing the change.
    • To trigger the Asana integration to move the related ticket across the Skate Dev board, each ticket on the PR must have the form Asana Ticket: <ticket url> and the particular ticket must be on the Skate Dev board (so if it's a subtask you'll need to manually add it to the board)
  2. New pull requests will automatically kick off testing. Wait for the tests to finish (about 10 minutes.)
  3. Once all the the automated tests pass, request a review from a team member. Update the Asana ticket to "In Review."

Development Deploys

Merge Branch

When a new feature has passed review, you can merge the code to the main branch. Using the "Squash and Merge" button will give you the opportunity to consolidate multiple branch commits with one message.

Delete the branch after merging has completed.

Deploy to Skate-Dev

After merging, using Github Actions or the button in your email, approve and deploy to dev (process takes about 10 minutes.) If the deploy ran successfully, update the Asana ticket to "To be released to prod."

New changes can now be found on Skate dev.

We normally allow a day or two before deploying to prod to ensure everything looks good on dev and to give an opportunity to check for errors in the logfiles.

Optional: Deploy to Skate-Dev-Blue

Use Github Actions to deploy a specific branch to Skate-Dev-Blue to stage changes that are expected to have visible front-facing consequences.

Production Deploys

1. Check that dev is in a good state

Check skate-dev to ensure that it's in a good state. Also check the Sentry skate-backend and skate-frontend projects' dev environments to make sure there are no surprising errors.

If there are, remedy those before deploying.

2. Check Splunk and Sentry to get a baseline for production

For Splunk, start by loading this search, and then exclude terms related to errors or warnings that seem to happen a lot (Geonames is a common culprit to ignore) until you see no results. This is your baseline search query.

For Sentry, check both the skate-backend and skate-frontend projects.

3. Actually perform the deploy

The simplest way to deploy is as follows:

  1. Run the script mix deploy.prod. This will open a release page in the browser.
  2. Click Generate release notes
    • Double-check that the tag is correct. It should be in the format YYYY-MM-DD-N, where N is used to differentiate between multiple releases in a given day and starts at 1.
    • Double-check that the release notes reflect the PR's that had been merged since the last release.
  3. Click Publish release
  4. Approve the release. You can do this in one of two ways:
    • Navigate to the "Deploy to Prod (ECS)" GitHub Action page, select the latest release (which should match the tag that you just created), and approve it. OR
    • Check your email for an email about a release needing approval. Click the link in that email and approve the deploy from the GitHub page that it brings you to.
  5. Watch it go! (This will take a while, so make sure you have a nice cup of coffee or beverage of your choice.)

4. Monitor the new version

Click around in Skate and double-check that things still look like they're working, especially any pages or components that were updated.

Return to your Splunk query created in step 1. You should continue to see no new results.

In Sentry, check the skate-backend and skate-frontend projects again. You shouldn't see any new errors.

If you go a half hour without seeing any issues, then you're good to consider the deploy successful. Mark any Asana tickets associated with this release as completed.