Skip to content

Case study

SailTac: from empty folder to a boat 250 miles offshore.

Offshore sailboat racing instruments, multi-model weather routing and an automated post-race debrief.

Shipping productSolo buildWindows desktopPaid, with commerce

The problem

Racing instruments are either toys or ten thousand dollars.

Offshore racing crews sit between two bad options. Consumer sailing apps show you a compass and a map. Professional instrumentation systems do everything, cost more than a suit of sails, and assume a dedicated navigator who has been trained on them.

The gap is a mid-fleet racing boat with real instruments on the mast, a few laptops and tablets aboard, and nobody whose full-time job is the software. They want the boat's own data rendered usefully, a routing opinion they can argue with, and an honest account afterwards of where the race was lost.

At a glance

What it's built from, for anyone who cares — and safe to skip if you don't.

Application
Electron, React, Zustand, Vite, Tailwind CSS
Server
Node.js, Express, WebSockets, TypeScript
Data in
NMEA 0183 over serial and TCP, NMEA 2000 via gateway, AIS
Distribution
NSIS installer, Cloudflare R2, signed delta updates
Licensing
Ed25519 offline keys, one per boat, 14-day grace period
Commerce
Next.js on Vercel, Stripe, Resend, Cloudflare DNS

What was built

Four systems, one product.

Instruments that work with no internet at all

A racing boat is covered in sensors — speed through the water, wind, depth, heading, position — and they all talk to each other over a cable in an old marine dialect. The app listens in on that conversation and puts it live on every phone, tablet and laptop on board. Each person arranges their own screen, because the navigator and the person steering want different numbers in front of them. None of it needs a connection, which matters, because offshore there isn't one.

Ten weather forecasts instead of one

Every forecast disagrees with every other forecast, and most tools hide that by quietly picking one. This runs ten of them and shows you where they part company — usually the single most useful thing on the screen, because it tells you which part of your plan is really a bet. After the race, each forecast is marked against the weather the boat actually got, so over a season you find out which one to trust in which conditions.

A debrief nobody can argue with

Crews reconstruct a race from memory, and memory is generous to whoever is telling the story. So every second is recorded — where the boat was, how fast, what the wind was doing, which sail was up, who was steering — and turned into a report afterwards: where the time went, how each person at the wheel did and in what conditions, and whether the boat was going as fast as it was capable of going.

The unglamorous half — actually getting it to people

Building the thing is half the job. The other half is a stranger being able to buy it, install it and keep it up to date. That meant a licence that works with no internet at all, covering every device on one boat, with a fortnight's grace after it lapses — because a billing problem should never be the reason you can't race. An installer. Updates that arrive in a few megabytes rather than re-downloading all eighty. And a shop that takes the payment and sends the licence out. This is the half where most side projects quietly stop.

The hard part

The bug that looked like data loss — and wasn't in the code.

After an update, the app opened as though it had never been used. No races, no marks, no boat setup — the digital equivalent of coming back to an empty house. It insisted it was looking in the right folder. It insisted that folder was fine. It found nothing there. Meanwhile all 5,768 files were sitting on the disk exactly where they should be, perfectly visible to anything else that looked.

The culprit was the antivirus. It had decided an unfamiliar program was worth isolating and, rather than blocking it or warning anyone, handed it a fake empty copy of its own data folder. Not an error, not a prompt — a convincing lie. And only a partial one: the licence file came through fine while the races did not, which is precisely the sort of evidence that sends you hunting in the wrong place for a day.

Finding it meant testing one candidate folder at a time, on a single boot, using the real application rather than a small test script — because a small test script wasn't treated the same way, and had already produced a confidently wrong answer. The trigger turned out to be the location itself: anything stored in the standard per-user folder that Windows tells every developer to use. Moving the data out fixed it. Shipped alongside that: a migration that refuses to run if it spots the fake empty folder, and a small record kept outside the data folder entirely, so a copy of the app that has been isolated can notice and say so instead of greeting someone with a blank screen.

Why this is in the case study

Because it is the actual job. Anyone can build the feature. The value is in the hours spent proving which of five plausible explanations is true, refusing to ship the fix that merely makes the symptom go away, and building the detector so the next person to hit it gets a warning instead of a mystery.

The test

It got raced.

The deadline was not a sprint review. It was a 250-nautical-mile offshore race from Port Huron to Mackinac, with the author aboard the boat the software was written for, running the build he had shipped days earlier.

That is a materially different standard. There is no hotfix at 3am in the middle of Lake Huron, no cell coverage, and no patience for a dialog box. Everything about how the product is built — offline first, degrade rather than fail, a licence that expires into a grace period instead of a lock screen — comes from having to live with the consequences personally.

Want something built to that standard?

Same engineer, same approach, whatever the domain.

Or go look at the product itself at sailtacperformance.com.