Epochron Stopwatches Groups Settings About
01

About

Professional timing made simple, reliable, and accessible to everyone.

Why This Exists

A few years back, I went to a track meet to watch my old college team compete. I tried timing some runners with my phone's stopwatch, wanting to see how the team had progressed since I was on it.

I was trying to time 3 multiple people and ended up spending the entire time focused on how to make my mess of a timer work instead of actually watching the race and taking split on the side. I lost track of whose splits were whose and what each split was supposed to indicate/record (ex. I took a split when they passed/were passed key people, or when they fell, as well as their laps and 200m splits). At the end, I was never really sure of whose splits were whose and felt like I wasted my time and effort. I did it for a couple other races with similarly poor results. I looked at other people at the meet, and they seemed to simply introduce more people, and have each person time a single person/relay.

The experience stuck with me. Handling multiple timers gracefully seemed like something some timing company or even a couple junior developers would have solved it already. More importantly, I'd only tried timing a couple races out of an entire meet.

Coaches and athletes deal with this constantly while trying to focus on what actually matters which is supporting their team, cheering at the right moments, giving real-time feedback. It seemed ridiculous that such a basic need was forcing people to choose between getting useful data and being present for their athletes. It was also frustrating that companies are out there building extravagant tools requiring very complex code, and yet solutions to my problem are still common. So while I was watching TV I'd idly sketch out some ideas of what one might look like.

But, then COVID-19 lockdown happened about 10 months later and I had a lot of time on my hands. So I decided to try building my own. I built it in ~3 weeks, working on it while I watched TV after work. It had no polish whatsoever, but it worked. I posted it to Reddit, and got some really helpful objective and functional feedback. Within a couple weeks I had about a couple hundred weekly users. I thought they would all eventually forget about it, but the numbers slowly creeped up, despite me not posting more about it.

I would use it periodically myself when I needed it. But I thought it was interesting that apparently other folks do too. This kept me thinking about it every few weeks. I would think of how I could have done a better job.

Over the course of a few months I came up with features it could use until I had a nice laundry list of new features to add that seemed worthwhile. Then I figured out how I would need to build it so I could continue adding stuff to it in the future. This is important because I wanted it to be local-first. Since with local-first apps you can't restructure the data on your own between upgrades, I knew I had to get the fundamentals of it exactly right ahead of time. Once I had that, I knew I was ready to build version 2.

This is that Version 2. Same fundamental idea as the first, but rebuilt to be more reliable, easier to use, and easier for me to work on.

02

Version 2Technical Details

The Problem with V1

In version 1, I was using an early version of VueJS which did not have services for inter-communication across an application. This made cross-communication between different parts/page of the application very difficult.

The Solution

Angular 20. I decided to build the second version with Angular v20, which has very robust support for intercommunication through services, has dependency injection to manage memory/dependencies better, and has signals to manage the state of the user interface easier.

The Problem with V1's Data Model

V1 stored stopwatch state as a snapshot that got continuously overwritten. History was collapsed into a single running total, and what actually happened along the way was discarded. This made the data model fragile in ways that directly limited what the app could do.

What V2 Makes Possible

By recording every action as a discrete timestamped event and deriving state from that history, a lot of things that were hard or impossible become straightforward:

  1. Adding, removing, or editing a split is a clean operation with no risk of silently corrupting the rest of your data.
  2. Adding a new kind of marker fits into the same structure without touching anything else.

The Problem

During a race, the people running stopwatches want to focus on the race, not on manually crunching numbers after the fact. But even with good split data in hand, knowing what's likely coming next is just as valuable as knowing what already happened; and mentally projecting future splits while simultaneously timing, coaching, and watching is simply too much to ask of anyone. If you're busy predicting, you're not acting.

A Data-Driven Approach

Rather than applying a single fixed formula, the analytics layer runs multiple strategies simultaneously and weighs their confidence against each other to surface the most credible results. Currently that's fifteen strategies, covering approaches like detecting rhythmic patterns in your split gaps, inferring your activity type from pace signatures, recognizing athletes' natural tendency toward round numbers and familiar lap fractions, and identifying the underlying distance unit your session is structured around.

For now that's focused on predicting upcoming splits. The goal is to free you up to actually do something about what's coming (e.g. give feedback, make a call, be present, etc) rather than spending that time doing the math yourself. The architecture is in place to go well beyond that over time (trend detection, anomaly flagging, benchmark comparison, etc.) without needing to change how the underlying data is collected or stored.

03
The Point

Good tools are built to be used. Existing solutions provided simple tools at professional pricing. This one provides a borderline professional tool at no cost.

Result: This does more than most expensive stopwatches, costs nothing, and your data stays yours.

Privacy

It's completely private because there's no reason to have to store your stopwatch data on a server somewhere. And I don't have to run/pay for a server.

Privacy was actually a by-product of my original desire to have a stopwatch that didn't need internet access and for it to be free. A lot of track/cross country meets are in areas with poor cell reception, so I wanted mine to work reliably. It also helped that the tooling for front-end only web applications was hitting maturity at the time.

Reality: I can see how many people created a stopwatch, or created splits. I can't tell anything about you, your stopwatch or your split.

04

FrequentlyAskedQuestions

Account

Why do I not need an account?

All your information is stored locally on your device, so there's no need for an account or a server.
Accuracy

How accurate is the timing?

Uses the same Web API that powers most online stopwatches. Accurate to milliseconds. In practical testing, it seems to match dedicated timing devices within 0.01 seconds.
Compatibility

Will this work on my device?

Works on any modern browser (Chrome, Safari, Firefox, Edge). Tested on iPhones, Android phones, iPads, and laptops. If your browser was released in the last 3 years, you're good.
Reliability

What happens if I accidentally close the browser?

Your timers keep running. Everything is saved automatically. Open it back up and they'll be there.
Cost

Why is this free?

Because I built it for myself and figured other people might find it useful. And I don't want to turn a side project that costs me nothing into a job.
Use Cases

Is this a replacement for meet management software like MileSplit or chip timing?

No. This is for coaches and athletes who need to time things accurately and keep that data organized while on a budget. If you're running a fully officiated meet, you need dedicated infrastructure. If you're timing your team at practice or watching splits from the infield, this is built for that.
Group Timing

Explain the group timing modes.

Timing modes control how the stopwatches in a group coordinate with each other.
  • Parallel: all timers run independently but share bulk controls (start, stop, reset, lap, and split).
  • Synchronized: like parallel, but timers are started and stopped together.
  • Sequential: one timer runs at a time. Hitting "Next" stops the current leg and starts the next one automatically, which is how relay handoffs actually work.
  • Independent: timers share a group for organization only, with no coordination between them.
Most tools give you independent timers and call it done. The distinction matters when your timing context has structure; a relay has a sequence, and a heat has a shared start.
Analytics

What does the stopwatch analytics actually show?

Right now: split/lap predictions of a single same timer based on it's data. The data structure is built to support more over time, and I'd rather show you what it does than promise what it might.
Features

What about [some niche feature]?

Maybe! Send me your use case on GitHub. I'm more interested in solving real problems than adding features nobody uses.
Offline

Does it work offline/with no cell service?

Yes. Everything runs locally. You could time at the bottom of a canyon with zero service and it works perfectly.