A terminal stopwatch with split tracking, persistent state, and calendar export. Built with Bubble Tea.
timer_demo.mov
- Millisecond-precision stopwatch
- Split tracking with lap times and timestamps
- Store State with SQLITE DB — the timer keeps running even after the app is closed. Reopening the app resumes from where it left off
- Editable split names with inline text inputs
- Delete splits (merges elapsed time into the previous split)
- Fullscreen / inline display toggle
- Export splits to
.ics(iCalendar) or asgwsCLI commands for Google Calendar
git clone https://github.com/jwc20/stopwatch-tui
cd stopwatch-tui
go build -o stopwatch-tui .
./stopwatch-tui| Key | Action |
|---|---|
s |
Start / stop the timer |
p |
Record a split |
r |
Reset (only available when stopped) |
↓ |
Enter edit mode — focus the first split |
e |
Export splits to .ics |
g |
Export splits as gws calendar commands |
f |
Toggle fullscreen |
q / ctrl+c |
Quit |
| Key | Action |
|---|---|
↑ / ↓ |
Move between splits |
| type | Edit the split name |
ctrl+d |
Delete the focused split |
esc |
Exit edit mode |
Each split row shows:
> 1. 00:12.345 (+00:12.345) 2026-03-05 10:32:01 [My event name_]
2. 00:25.678 (+00:13.333) 2026-03-05 10:32:14 [Split 2 ]
- Cumulative elapsed time
- Lap time since the previous split (in parentheses)
- Wall-clock timestamp when the split was recorded
- Editable name field (used as the event title on export)
When a split is deleted, its elapsed time is merged into the previous split so the total elapsed time is preserved.
Exports splits as a standard iCalendar file (splits_<timestamp>.ics) using golang-ical. Each split becomes a calendar event spanning from the previous split's timestamp to the current one. The event summary is the split name (or Split N if unnamed).
You must enable Google Calendar API and set up credentials on Google Cloud to use this feature.
Exports splits as a shell script (splits_<timestamp>.sh) containing one gws calendar +insert command per split, ready to run against Google Calendar via the gws CLI.
gws calendar +insert --summary "Morning run" \
--start "2026-03-05T10:32:00-08:00" \
--end "2026-03-05T10:44:12-08:00" \
--description "Split 1 of 3 | Elapsed: 00:12.345 | Lap: 00:12.345"Review the file before running: cat splits_<timestamp>.sh, then execute with ./splits_<timestamp>.sh.
.
├── main.go # TUI model, keybindings, view
├── db.go # Store state into db
├── ics.go # iCalendar export
├── gws.go # gws CLI command export
└── stopwatch/
└── stopwatch.go # Stopwatch model (tick, split, delete, reset)

