
I check public transit departures dozens of times a day. The official apps are slow, cluttered, and half of them want you to create an account just to see when the next tram leaves. So I did what any developer with a free weekend would do — I built my own.

**EVA-PWA** is an open source Progressive Web App for real-time departure times and trip planning across the Basel and Baden-Württemberg region. It's live at [ov.b65.ch](https://ov.b65.ch), installable on your home screen, and designed to feel like a native iOS app on every platform.

## Departures at a glance

The home screen shows all your saved stops with grouped departures and a live countdown. The countdown updates locally every 15 seconds without reloading — and it changes color as the clock runs out. Blue means you have time. Orange means you should start walking. Red means hurry. "Now" means you missed it.

You can configure a **refresh interval** per your preference — every 15 seconds, 30 seconds, one minute, or two minutes.

![EVA-PWA departure board — light and dark](/storage/eva-pwa-home.png)

## Finding and filtering stops

Searching for a stop uses the EFA autocomplete API with debouncing, filtered to the Swiss region, so you don't get flooded with results from across Germany. Once a stop is added, you can set **line and direction filters** for it — so you only ever see the routes you actually care about. No more scrolling past ten buses going the wrong way.

## GPS and nearby stops

**GPS sorting** automatically reorders your saved stops by distance to your current location. But the more useful part is the nearby stop detection — if there's a stop close to you that you haven't saved, the app shows it automatically at the top with live departures. That's handy when you're somewhere new and just need to know what's leaving from around the corner.

## Trip planner

The built-in **trip planner** lets you search connections between any two stops by departure or arrival time. It keeps a history of your recently used stations, so you don't have to type the same names over and over. There's also a one-tap **home button** — it finds your nearest stop via GPS and fills in your configured home stop as the destination. Or the other way around.

Trip results show the full connection with transfers, and tapping into a connection gives you the complete **leg timeline** — intermediate stops, platform information, and any active disruption messages expanded inline. If you want to share a connection with someone, there's a share button that uses the native share sheet or copies a link to your clipboard.

![EVA-PWA trip planner](/storage/eva-pwa-trip.png)

## Config that travels with you

I run this app on my phone and my iPad. Setting everything up twice is annoying. So I added a **QR code export** — it encodes your entire stop configuration into a QR code or a URL. Scan it on another device, and you're fully configured in seconds. You can also import by pasting a base64 string directly if you're on a desktop.

## Dark mode and iOS feel

The app has a proper **dark mode** with an iOS-inspired color palette — the same deep blacks and elevated card surfaces you'd expect from a native app. It respects the safe area insets on iPhone, uses the system font stack, and the bottom navigation sits cleanly above the home indicator. It's the kind of detail that makes a PWA feel like it actually belongs on your phone.

![EVA-PWA in dark mode](/storage/eva-pwa-home-dark.png)

## Install it

Open [ov.b65.ch](https://ov.b65.ch) on your phone and add it to your home screen — that's it. No App Store, no account, no tracking. Works on iOS, Android, and desktop.

The source is on GitHub at [simonjenny/EVA-PWA](https://github.com/simonjenny/EVA-PWA) — contributions welcome.

```bash
git clone https://github.com/simonjenny/EVA-PWA.git
cd EVA-PWA
npm install
npm run dev
```
