Inspiration

Riding the Long Island Rail Road from Stony Brook is a daily puzzle: is the next train direct, where do I transfer, which platform, and is it worth waiting for the next one? The official apps are accurate but dense, and nothing about them feels like riding a train. The hackathon theme, Steel and Steam, gave us an excuse to ask: what if checking a train time felt like stepping into a Victorian station, with the real, live data of a modern railroad underneath?

[Add one or two sentences about your own commutes or why this route matters to your team.]

That became BrassLine: "Every line, right on time."

What it does

BrassLine is a mobile-friendly web app for the LIRR Port Jefferson Branch and the rest of the system, wrapped in a steampunk interface.

  • Real timetables. Departures come from the MTA's official LIRR GTFS schedule feed, with the correct weekday, Saturday, and Sunday service. Choosing a time shows every train from then on, rolling into the next service day after the last train.
  • Transfers handled. Trips from Stony Brook to Penn Station or Grand Central Madison include the connection at Huntington or Jamaica, with real arrival and travel times.
  • Live status. Trains with MTA GTFS-realtime data show a Live badge with real delays and cancellations. Everything else honestly says Scheduled.
  • Interactive map. A parchment-style railway chart over a real map of Long Island, with the lines drawn along the actual track geometry.
  • Stationmaster Abernathy. A Gemini-powered chatbot who stays in Victorian character but answers from the same schedule you see on screen, so his times match the timetable. [Voice: you can talk to him and he answers aloud.]
  • Dynamo. A brass pressure gauge and a toll-and-time savings panel, clearly labeled as estimates.
  • Vicinity guide. Places to eat and drink near your station.
  • Passenger's Ledger. A profile with fare categories based on the MTA's actual published rules.
  • Scan and go. A QR code opens the live site on any phone, no install needed.

How we built it

  • Frontend: React, TypeScript, and Vite, styled with a custom Victorian theme (brass, parchment, oxblood, verdigris).
  • Schedule data: We compiled the MTA's static GTFS files (stops, stop_times, trips, calendar_dates) into a compact schedule at build time. A trip's duration is simply

$$t_{\text{trip}} = t_{\text{arrive, destination}} - t_{\text{depart, origin}}$$

and for transfers we pair each arrival at the hub with the first connecting departure that leaves after it.

  • Live data: A serverless function decodes the MTA's GTFS-realtime Protobuf feed, caches it for 20 seconds, and the app merges delays and cancellations into the timetable.
  • Chatbot: A serverless endpoint streams Gemini responses to the browser. The API key lives only in server-side environment variables, and the chatbot receives the user's selected route and the next departures as context.
  • Map: Leaflet with OpenStreetMap-based tiles, a sepia filter for the parchment look, and station coordinates from the GTFS feed.
  • Deployment: Vercel, with a public URL and a QR code.
  • Tooling: We built much of the app with Google Antigravity, writing precise prompts, testing in the browser, and checking the output against the official TrainTime app.

Challenges we ran into

  • Times that didn't match the real app. Our first timetable looked right but was off by several minutes. We compared it with TrainTime and traced the bug to the service calendar: a value of "today" wasn't a valid date, so the code silently fell back to the weekday schedule on a Saturday. After the fix, every departure and arrival matched TrainTime exactly.
  • Fake details hiding in a "real" app. We found that track numbers and "On Time" statuses were being generated, and that some fare discounts weren't real LIRR programs. We removed them, added true realtime data, and rewrote the fare categories from the MTA's published rules. Showing Scheduled beats showing a confident guess.
  • GTFS quirks. Trips after midnight use times past 24:00:00 and belong to the previous service day, so "show me trains from now on" needed care around midnight.
  • Going live. The live-data and chatbot routes worked only inside the dev server, so we rebuilt them as serverless functions, fixed Windows PowerShell restrictions, set environment secrets, and debugged a QR code that looked right but didn't scan.
  • Map clutter. Showing every train and station made the map unreadable, so we limited labels to major stops and trimmed what we drew.

Accomplishments we're proud of

  • A working public app built on real MTA data that matches the official app.
  • A chatbot that is in character and accurate, because it reads the same data as the timetable.
  • A theme that makes a commuter tool memorable without hiding where the data comes from.
  • Auditing our own work and removing claims we couldn't back up.

What we learned

  • Verify against a source of truth. Comparing our output with TrainTime caught bugs we would never have noticed by eye.
  • Honest labels build trust. Scheduled, Live, and Estimate tell users how much to rely on each number.
  • Real transit data is messy but powerful. GTFS and GTFS-realtime reward careful handling of calendars, stop IDs, and time zones.
  • Break big requests into small, testable steps when building with an AI coding tool.
  • Keep secrets on the server. API keys belong in environment variables, never in the browser.

What's next

  • Platform and track info wherever the realtime feed provides it.
  • Real service alerts from the MTA alerts feed.
  • Saved routes and push notifications for your usual train.
  • Verified, real places in the Vicinity guide, with a food search.
  • Support for the entire LIRR system, plus a refresh script for the schedule feed (the current one covers service through early November 2026).

BrassLine is an independent student project and isn't affiliated with or endorsed by the MTA or the Long Island Rail Road. Schedule data comes from the MTA's public developer feeds.

Built with: React, TypeScript, Vite, Leaflet, OpenStreetMap, MTA GTFS and GTFS-realtime, Google Gemini API, Vercel, Google Antigravity

Share this project:

Updates

Submission history