How I built a Golf Shot Analyzer

---
Building a Golf Shot Analyzer with Claude Code
May 11, 2026
---
I've been playing golf seriously for about a year. My launch monitor captures
everything β ball speed, carry distance, apex height, launch angle, shot curve
β but the default export is a flat CSV that tells you almost nothing at a
glance.
I wanted to actually see my shots.
---
The starting point
The data lived across two sessions in two separate CSV files, with a Google
Sheet that had accurate club assignments the CSVs were missing. Not a clean
situation. About 340 shots total, with 114 where the club was recorded as ? β
shots I'd hit without logging which iron I'd grabbed.
The goal was simple: one interactive tool, all sessions, filter by club or
date, see where every shot went.
---
How it was built
I used Claude Code to build the whole thing in a single conversation. No
boilerplate project setup, no scaffolding β just described what I had and what
I wanted.
The first step was fixing the data. Claude read both CSVs, cross-referenced
the Google Sheet (via the Google Drive MCP), and corrected 19 misclassified
shots β shots 24 through 42 from the April session had all been tagged as 8i
when they were actually 7i, 6i, and 5i.
Once the data was clean, the visualizer itself took shape quickly. A custom
canvas trajectory view renders each shot as a parabolic arc β apex Γ sin(Ο Γ
distance/carry) β which turns out to be a surprisingly good approximation of a
real ball flight. The bird's-eye dispersion scatter uses Chart.js. Everything
else is vanilla JavaScript, no framework.
The whole thing is a single self-contained HTML file. No server, no build
step.
---
Reading from Excel directly
Early versions embedded the shot data as a JavaScript blob inside the HTML.
That worked, but it meant regenerating the file every time I added a new
session.
The final version uses SheetJS to parse the Excel file directly in the
browser. Drag Shot Data.xlsx onto the drop zone, and the tool reads it fresh.
Date filters and club tabs populate automatically from whatever sessions are
in the file. Nothing is uploaded anywhere.
Adding a new session means updating one spreadsheet, not touching any code.
---
What surprised me
The trajectory chart was the most useful thing I didn't expect to need.
Looking at ball speed or carry as numbers tells you one thing. Seeing 30 arcs
stacked on top of each other β some tight and repeatable, some wildly
inconsistent β tells you something completely different about what's actually
happening in your swing.
The predicted shots (marked in amber) stand out immediately too. A cluster of
amber dots in a completely different carry range than the named-club shots is
a signal worth investigating.
---
How to use it
Open golf_visualizer.html in any browser. You'll see the drop screen first.
Load your data. Drag your Shot Data.xlsx onto the drop zone, or click to
browse. The app reads it once and renders everything. Use the β© Load different
file button to swap files anytime.
Filter by session. The session dropdown in the top right lets you isolate a
single date or view all sessions together. Tabs reset to match whichever
session you pick.
Filter by club. The tab bar shows every club in the current session with shot
counts. Click any tab to focus on that club β all three charts update
together.
Inspect a shot. Hover over any arc in the trajectory chart to see the details
float alongside it. Click to pin it β the selected arc turns gold, everything
else fades out, and a detail card appears in the stats panel. Press Esc or
click empty space to deselect.
Bird's eye view. The scatter chart shows lateral landing position versus carry
distance. Each dot represents one shot. Click a dot to select it across both
charts simultaneously. Predicted shots appear in amber.
Stats panel. Average carry, apex, ball speed, and launch angle update live as
you filter. The range beneath each number shows floor and ceiling across the
current selection β more useful than the average alone when consistency is
what you're working on.
---
The Excel file
The spreadsheet has one sheet called shot_data with a Date column, a Club
column, and all the launch monitor fields. Adding a new session is just
appending rows with the new date. The tool derives everything else β Predicted
flags, date dropdowns, club counts β from whatever's in the file at load
time.
No configuration. Just data.
---
Built with Claude Code, Chart.js, and SheetJS. Data from a InRangeβ’ tracking session hosted at Hazendal Driving range.
---