Here it is in the flesh, in the wild, my latest project of 2025, the MBTA Screen. We’ll have a lot more to talk about with the UI/UX, but let’s start with hardware.  The screen runs on a Raspberry Pi 5 with 2 GB of RAM, and the screen is a Pimoroni

MBTA Screen

The MBTA Screen is a 4-inch, Raspberry Pi-powered touchscreen that shows real-time departure information for any MBTA stop. With a single tap, the screen comes alive and shows you loads of information about upcoming train departures from my nearest stop, delays, and the weather - all so I don’t need to fumble with my phone before leaving.

And the best part - clicking on any departure brings you to a screen where you can plan out how you’ll be connecting to a different line - answering questions such as “How long will I be waiting?”, “Will I need to run for the train?”, “Can I can take this later train instead?” and “What time will I get to my destination?”.

The MBTA Screen was meant to be a way to quickly check all of this - a screen that is small, mighty, full of data, and easy to use, and has quickly become my favorite gadget to use in my apartment.

Timeframe: September 2025 - Present

 Here it is in the flesh, in the wild, my latest project of 2025, the MBTA Screen. We’ll have a lot more to talk about with the UI/UX, but let’s start with hardware.  The screen runs on a Raspberry Pi 5 with 2 GB of RAM, and the screen is a Pimoroni

Here it is in the flesh, in the wild, my latest project of 2025, the MBTA Screen. We’ll have a lot more to talk about with the UI/UX, but let’s start with hardware.

The screen runs on a Raspberry Pi 5 with 2 GB of RAM, and the screen is a Pimoroni Hyperpixel 4.0 with touch enabled. The case is 3D-printed in PETG (rather than PLA since the Pi doesn’t have a heatsink on it, you’ll see why shortly), and connected to it is an official 27W Pi 5 power adapter that I had lying around (totally overkill, obviously).

The screen resolution runs at 800×480, however, the MBTA Screen software runs at 533×320, which is upscaled at 150% - mostly for readability because of the Hyperpixel’s dense PPI.

By the way - my phone is doing a really bad job exposing the screen - it is not this washed out in person! And the keen eyed among you may have realized that this sits below PyWeather 3 next to my door - very nicely done!

 Here’s a side profile of the MBTA Screen hardware package.  There isn’t much to talk about on the Pi side itself - it’s just a Raspberry Pi running Raspbian Trixie with the Pi Desktop enabled. Enabling the Hyperpixel is as easy as adding a dtoverlay

Here’s a side profile of the MBTA Screen hardware package.

There isn’t much to talk about on the Pi side itself - it’s just a Raspberry Pi running Raspbian Trixie with the Pi Desktop enabled. Enabling the Hyperpixel is as easy as adding a dtoverlay in the boot config file, then setting the mouse to run in multi-touch mode.

The Pi has a few functionalities I’ll talk about here. First - running the screen. It’s a Chromium kiosk wrapper around a React + Mantine website hosted on my web server. The Pi has a minimal Python + Flask based HTTP server for controlling the kiosk service - mostly so it reloads the service if an update is detected, and for the settings menu in the screen. Finally - there’s a bit of labwc configuration done to turn off the screen backlight if there’s been no touch in the last 2 minutes. In the frontend software, the display shows all black as well if no taps are detected in 2 minutes.

When the screen is off - it is doing nothing to save power, network data, and API calls. Only when the screen is on is it reaching out to the MBTA API, and loading data on the screen takes under a second after tapping it on. It’s very quick.

 Folks - here it is! You’re looking at a screenshot from a new stack of software that I’ve made. Since the MBTA Screen is just a React website, I can capture everything on my laptop. If you have a wide screen, now is a great time to reduce your windo

Folks - here it is! You’re looking at a screenshot from a new stack of software that I’ve made. Since the MBTA Screen is just a React website, I can capture everything on my laptop. If you have a wide screen, now is a great time to reduce your window width because Squarespace does not like tall images.

First - the screen has automatic dark & light mode - but it is not controlled by you! It is controlled by the time of the day. The screen starts off in dark mode, then comes into light mode about 10 minutes before the sunrise. The opposite happens at sunset. This is very similar to OctoCam’s night mode functionality using real sunrise/sunset data.

At the top is a persistent status bar that sits across the UI. On the homescreen, it shows a greeting and the time in the upper right corner. Whenever you’re not on the homepage, the greeting is replaced by a back arrow to bring you back to the homepage.

Below that is the current weather locally sourced from Beacon Hill Weather! The screen uses the API I built in that project to get weather data. Tapping this brings you to a page with lots of weather details - more on this soon.

Below that is the current alerts on the Red Line - no alerts when I took this photo, but tapping that brings you to another page we’ll talk about soon.

 And then you get to the train departure times. Lots going on - but everything is pretty simple when you look at it. The format of the display tries to mimic the MBTA countdown clocks as closely as possible - including showing ARR/BRD when a train is

And then you get to the train departure times. Lots going on - but everything is pretty simple when you look at it. The format of the display tries to mimic the MBTA countdown clocks as closely as possible - including showing ARR/BRD when a train is arriving/boarding. The screen automatically grays out any departures that are too far away - there’s no way I can run for a train that’s boarding right now.

Sparkles next to a train indicate a new train - and those new trains expose their occupancy data through the API, so that is shown here as well. You’ll also see a run icon next to the Alewife departure in 1 minute. At least for my apartment, it takes about 2 minutes to get to the platform, if the train is supposed to come any sooner, it shows a run icon saying you better get a move on.

Another icon not present is the number 4 in a box (you’ll see an example of this in a different form later) - this is to indicate a shorter Red Line train is being used, and that might mean it’ll be more packed than usual.

Updates are retrieved every 12 seconds from the MBTA API, and animations on this page mean that predictions come in and out very smoothly.

At the top of each departure box is an arrow to show more departures - 3 are shown by default, but up to 6 can be shown.

 Whenever trains are more than 20 minutes away, I prefer to show the actual time that it will be arriving at so you don’t have to do a lot of mental math. Plus, it’s very rare that I think to myself, yes, let me take this train arriving at this exact

Whenever trains are more than 20 minutes away, I prefer to show the actual time that it will be arriving at so you don’t have to do a lot of mental math. Plus, it’s very rare that I think to myself, yes, let me take this train arriving at this exact time. It’s more of a ballpark estimate because these predictions will more than likely drift if you kept track of them.

 Below this are two more buttons - showing departures from the Bowdoin Blue Line stop (down the road from me), and the settings page which we will talk about later!

Below this are two more buttons - showing departures from the Bowdoin Blue Line stop (down the road from me), and the settings page which we will talk about later!

 Here’s that Blue Line page - with a few modifications to show up to 5 departures at once, and some helpful text reminding you of how long the walk is to Bowdoin.  You can see here that I’ve configured the “train isn’t reachable” and the “train can b

Here’s that Blue Line page - with a few modifications to show up to 5 departures at once, and some helpful text reminding you of how long the walk is to Bowdoin.

You can see here that I’ve configured the “train isn’t reachable” and the “train can be reached by running” thresholds - they’re all customizable in code!

 Coming back to the main screen - clicking on any Alewife-bound train shows the full timeline of the trip with all the stops, plus the trip consist (which train cars are part of a trip). Since there are no additional connections towards Alewife (tech

Coming back to the main screen - clicking on any Alewife-bound train shows the full timeline of the trip with all the stops, plus the trip consist (which train cars are part of a trip). Since there are no additional connections towards Alewife (technically you can get the Commuter Rail at Porter, but I limited connection options to rapid transit only for the time being), the trip timeline is expanded by default.

 For new trains that support occupancy data (some Red Line trains, all Orange Line trains), the trip consist comes alive with colors indicating the occupancy percentages for each car. Each color means something slightly different (going from many sea

For new trains that support occupancy data (some Red Line trains, all Orange Line trains), the trip consist comes alive with colors indicating the occupancy percentages for each car. Each color means something slightly different (going from many seats available to crushed standing room only) - but the percentage does help you figure out how crowded a car will be. Usually these numbers stay below 40% - but I’ve seen them as high as 70% on really bad days.

 But if you select a train going southbound towards Ashmont or Braintree, you’re presented with this screen instead. The trip timeline is condensed to show 1 stop - Charles/MGH, with a button to drop it down and show the full stop list + trip consist

But if you select a train going southbound towards Ashmont or Braintree, you’re presented with this screen instead. The trip timeline is condensed to show 1 stop - Charles/MGH, with a button to drop it down and show the full stop list + trip consist.

And here’s the magic of the MBTA Screen - the connections. The screen starts off by asking which station you want to connect at - for myself on the Red Line, you get three lines at the three downtown stations. For this demo, let’s connect at Park Street, as it’s the most complex showing of this feature.

 Next, you’ll be asked which direction you’re traveling in - westbound towards Copley, or Northbound towards Government Center. For this example, let’s say we’re going westbound on our trip.  For connections on the Orange Line - you stop at this scre

Next, you’ll be asked which direction you’re traveling in - westbound towards Copley, or Northbound towards Government Center. For this example, let’s say we’re going westbound on our trip.

For connections on the Orange Line - you stop at this screen, since you’re either going Northbound towards Oak Grove or Southbound towards Forest Hills. For the Silver Line - you go past this screen entirely - every bus goes east from South Station (it’s the first stop).

 Lastly, the screen asks us exactly where we want to go - with 6 options (4 for the Silver Line)! As a side note, the dropdown on the actual screen would be above the select box - but on my laptop with vastly more screen real estate, it likes to go b

Lastly, the screen asks us exactly where we want to go - with 6 options (4 for the Silver Line)! As a side note, the dropdown on the actual screen would be above the select box - but on my laptop with vastly more screen real estate, it likes to go below the dropdown.

The six options here represent the six different permutations you can take because of the 6 different permutations of Green Line branches you can get on. I decided not to list every single stop on the Green Line, nor allow you to select which combination of lines to use, but rather, just where are you going. Are you going down the B/C/D/E branch, or somewhere in between where multiple branches can serve you.

A similar thing occurs with the Silver Line, but it’s a lot less confusing. SL1/2/3 all serve up to Silver Line Way, then they branch out, so I list the options as Courthouse → Silver Line Way, then SL1/2/3 individually.

For this example, let’s pick the B branch - perhaps I’m going to Boston University for an ice hockey game. Hiding beneath the dropdown is a Find connections button.

 And take a look at that - I can see that with my train arriving at 9:35, I’ll be waiting 7 minutes for the train at 9:42. I can also see which trains come after that - usually 4 trains is enough for single-branch results, but on Boylston → Copley, t

And take a look at that - I can see that with my train arriving at 9:35, I’ll be waiting 7 minutes for the train at 9:42. I can also see which trains come after that - usually 4 trains is enough for single-branch results, but on Boylston → Copley, this screen has many more trains. Alerts for the Green Line are also shown in case there’s anything I need to know. If the train is stopped en-route, this screen also shows it!

The Green Line has its own suite of icons as well - this 1 represents a 1-car train (the MBTA API was glitching out the day I was making these screenshots and thought every GL train was just 1 car), along with specials for the new trains, googly eye trains, and the pride train as well.

At the bottom is a start over button, allowing you to go back and try a different connection on the screen.

 At the top, you can switch between different train departure times very easily - this is good when figuring out if a specific train you want to catch might be served by a later train, giving you a bit more time. In this example, I switched the scree

At the top, you can switch between different train departure times very easily - this is good when figuring out if a specific train you want to catch might be served by a later train, giving you a bit more time. In this example, I switched the screen to use all lines, so that’s why you see the C branch come up. You can also see that I might have to run for the B branch train, and the screen tells me where I need to be on the train for an optimal connection.

Fun fact: The connection times on the screen are actually accurate and measured! I spent about an hour going around the downtown stops with my phone and a stopwatch, getting off trains 5 times with people to see how long it takes to walk to each platform.

As a fun fact, the start over button will take you back to the original train you selected, NOT the one that you moved to as an experiment. That was a strange bug for a little bit…

 Clicking on the arrow of any train shows you a modal that brings up the same timeline of stops and when the train will arrive at that stop. If you know what stop you’re getting off at & the walking distance to your destination, you can effective

Clicking on the arrow of any train shows you a modal that brings up the same timeline of stops and when the train will arrive at that stop. If you know what stop you’re getting off at & the walking distance to your destination, you can effectively plan your entire trip on this screen and know your ETA down to the minute.

Scrolling to the bottom of the trip timeline also shows you the trip consist - for Orange Line connections, this will show the occupancy data of the train as of when you’re looking at the screen.

 Coming back to the home screen for a bit - this is the weather screen. Is it the best looking screen? No! But it’s not horrible considering this is basically a clone of the Beacon Hill Weather homepage adapted for a much smaller screen.  If you’ve e

Coming back to the home screen for a bit - this is the weather screen. Is it the best looking screen? No! But it’s not horrible considering this is basically a clone of the Beacon Hill Weather homepage adapted for a much smaller screen.

If you’ve ever visited the Beacon Hill Weather homepage, the order of the data is exactly the same, but split into many smaller boxes due to the very limited screen width.

 Further down the screen, rather than have a header for each section, then show the reading, I make it part of the same row so it flows like natural text. In my opinion it is giving 2010s UI vibes (like Windows 8 or something), but it works!

Further down the screen, rather than have a header for each section, then show the reading, I make it part of the same row so it flows like natural text. In my opinion it is giving 2010s UI vibes (like Windows 8 or something), but it works!

 And here is the full MBTA System Status page - which shows alerts for the Red, Orange, Blue, Green, and Silver Lines (SL is not pictured here, but it’s okay, it’s fake BRT anyway).  Of a note - the Green Line actually has 4 logical routes the MBTA u

And here is the full MBTA System Status page - which shows alerts for the Red, Orange, Blue, Green, and Silver Lines (SL is not pictured here, but it’s okay, it’s fake BRT anyway).

Of a note - the Green Line actually has 4 logical routes the MBTA uses for each branch, but if an alert occurs somewhere in, say, the central tunnel that affects all 4 lines, the alert gets duplicated to each branch (and shows up 4x here). On the backlog is a way to de-duplicate these alerts so it shows up once, but for now, it’s more of an annoyance than anything else.

 And as luck would have it when writing this page, an alert showed up. This is how it looks - the arrow indicating there’s a page behind the alert is hidden (but the entire alert box remains clickable), and how long ago the alert was updated is also

And as luck would have it when writing this page, an alert showed up. This is how it looks - the arrow indicating there’s a page behind the alert is hidden (but the entire alert box remains clickable), and how long ago the alert was updated is also shown. This is the case across the UI anytime an alert is shown.

 Finally, this is the settings screen, which allows you to screw around with the service a little bit - restart it if there’s a bug, etc etc.

Finally, this is the settings screen, which allows you to screw around with the service a little bit - restart it if there’s a bug, etc etc.

 Bonus screenshot time for more MBTA Screen action pictures - here is living proof of the screen very much showing that it will tell you when the MBTA is having a meltdown.  This night, I wanted to take the train to go out, but the screen said hold o

Bonus screenshot time for more MBTA Screen action pictures - here is living proof of the screen very much showing that it will tell you when the MBTA is having a meltdown.

This night, I wanted to take the train to go out, but the screen said hold on just a sec, all the trains are stopped, so we did rideshare instead (sad). But, it was very handy because the MBTA had not issued an official alert yet.

 Here is an example of the pride train modifier in action - the entire departure goes rainbow to indicate such. There is a green line car with a pride in transit wrap on it in Boston - and it runs year round! It’s always a treat to see it, so I thoug

Here is an example of the pride train modifier in action - the entire departure goes rainbow to indicate such. There is a green line car with a pride in transit wrap on it in Boston - and it runs year round! It’s always a treat to see it, so I thought it would be fun to bring that onto the screen.

As a note - this was earlier in the screen’s development so you can see how some typography was different.

 Lastly, this is a very early screenshot of the MBTA Screen with about a few days of development having happened. It looks entirely different - even the Pi is mounted the wrong way around (there were touchscreen issues in everything but the default o

Lastly, this is a very early screenshot of the MBTA Screen with about a few days of development having happened. It looks entirely different - even the Pi is mounted the wrong way around (there were touchscreen issues in everything but the default orientation, so I stuck with it). This early implementation also has the screen for Bowdoin departures further down, but you can’t see that in this photo.

The MBTA Screen has been such a fun project to work on - originally envisioned as a little side project, it’s ballooned into quite the cool project that I’m honestly incredibly proud of, exposed me to the MBTA API (something I’ve been wanting to do for way too long), and taught me a good amount about transit APIs & data. Perhaps one day I might sell these as a product - but that would be for the future.