howbadisthetrain.com is a small, independent project that scores every NYC subway line from 0 to 10 based on what's actually happening right now — delays, crowding, planned work, the lot. It's built for riders who want a quick honest read before they head to the platform.
Why
The MTA's own service status pages are accurate but unfriendly to skim — they were designed for commuters with spare time on the platform, not for someone deciding between the F and an Uber at 11pm on a Wednesday. We built the version we wanted to use: one screen, every line, ranked, with the numbers that actually matter at a glance.
What you get
- Every NYC subway line, ranked worst-to-best, on a single page.
- A per-line page with the current score, the one-line label, and a rough "vs. driving" cost/time comparison.
- Honest copy. The labels are written by a person (us), not generated — dry, occasionally snarky, and firmly on the side of public transit.
- A methodology page that names exactly what's real, what data is stub, and where the line is between signal and satire. Read it before you assume any number is gospel.
What we don't do
- We don't require an account. There is no signup, no login, no profile.
- We don't sell or share any data. The site sets no first-party cookies. Cloudflare's privacy-first analytics may be enabled server-side at some point; nothing user-identifying ever leaves your browser.
- We don't editorialize on the lines themselves beyond the tone of the labels — no safe/dangerous coding, no neighborhood commentary, no culture-war bait.
- We don't run sponsored posts or paid rankings. Ads come from Google AdSense only, and they only appear in the slots between content blocks, never on top of the score itself.
Who
One person, working on this in the open. The site is hosted on a small VPS, fronts the MTA's GTFS-realtime feeds (or stub data, until the live integration ships — see the methodology page for the scoring math), and earns revenue through Google AdSense. There is no team, no funding, no growth targets, and no roadmap beyond making the score honest and the page fast.
How it's built
- Next.js (app router) on Node 20.
- TypeScript end-to-end. Tailwind for styling, with a small custom palette that borrows from the MTA line colors but stays distinct from any single roundel.
- Docker + Caddy + Cloudflare for the serving stack.
- ISR + edge caching to keep the homepage snappy without hammering the MTA feed.
- No client-side analytics beyond Cloudflare's privacy-friendly web analytics (when enabled). No third-party tracking scripts beyond what Google AdSense sets.
Line colors
The colored ring around each line badge is the MTA-published line color, used here in a thin outline and matching text so it stays visually distinct from the official MTA roundel (which is filled solid). This site is not affiliated with, endorsed by, or sponsored by the MTA — the colors are publicly documented reference values, used to help riders identify their line at a glance.
What's coming
- Live MTA GTFS-realtime integration. The current scores are hand-curated; the goal is to recompute every line against the live feed every minute or so.
- Saved lines — bookmark the lines you ride, get a shorter list on the home page.
- Station-level detail for the lines that need it (lookin' at you, Times Square).
- Service-change lookahead for planned weekend work.
Open-source pieces
The site itself isn't open source (yet). The pieces that could be useful to other transit-data hackers — the MTA feed parser, the scoring math, the lineup of static assets — are something we'd consider releasing if there's interest. Email us if you'd find them useful.
Get in touch
Bug reports, scoring disagreements, line-color corrections, and methodology questions all welcome. Email [email protected] — we read every email.
See also: Methodology, Privacy, Terms.