Barberfishes keeps Hammerheads sharp, in the ocean and on your bike. Native-feeling data field enhancements for the Hammerhead Karoo.
Barberfish is a collection of data fields for the Hammerhead Karoo. They sit alongside the native ones, match their look, and quietly add a bit more: a 3- or 4-column HUD, a Tufte-inspired elevation sparkline, and configurable smoothing, color modes, color palettes, and thresholds per field. Everything is set up in the Barberfish app on your Karoo with live previews; changes apply mid-ride.
| Elevation sparkline below a 3-column HUD on the map view | Karoo native fields beside their Barberfish counterparts |
![]() |
![]() |
Most GPS bike computer manufacturers, Hammerhead included, don't publish the algorithms behind their built-in smoothing and ETA fields. Barberfish uses explicit, documented ones so the field's behaviour is something you can predict.
Grade is smoothed over distance rather than time, fitting an ordinary least squares line through the last 30 m of elevation. A fixed-window time average has to pick between jittering with every cadence stroke (short window) and smearing the start and end of a climb (long window). The OLS-over-distance variant sidesteps the trade by following the road instead of the clock: it holds steady at any speed and stops moving when you do.
ETA blends a 5-minute fast and 1-hour slow DEWMA of recent speed with a configurable prior, so the estimate sharpens as the ride goes on rather than starting from a generic guess. It is not yet gradient-aware, so the climb you can see coming will still pull the arrival time inward. The forward-looking replacement lives in Godot.
Most fields have a color mode that controls how the value sits on the background. None is the default and applies no zone coloring. Text colors the value with the zone color. Fill paints the background with the zone color and picks black or white for the value so it stays readable on top.
The Karoo background is white in light mode and black in dark mode. Text mode puts the colored value straight on that background, and palettes designed for one theme can read poorly on the other. Barberfish contrast-tunes each brand palette into a light and a dark variant so the colors stay legible against either background.
The tuning uses APCA: any color below the threshold for legible large text has its HSLuv lightness shifted until it passes, hue and saturation kept intact. Fill mode needs no tuning: the value drawn on top adapts to whichever zone color fills the background. The HSLuv palette is built around perceptually uniform lightness from the start and reads the same on both themes without correction. See docs/color-palettes.md for the full derivation.
Format options vary by category.
Duration fields (time, ETA, daylight) use one of three formats, all unambiguous at any length:
| Format | Under an hour | Over an hour |
|---|---|---|
| Racing | 23'45" |
1h23'45" |
| Clock | 0:23:45 |
1:23:45 |
| Segments | 23m45s |
1h23m45s |
Power Zone and HR Zone toggle between integer (3) and one-decimal float (3.4) display per field.
Speed, average speed, and cadence support threshold coloring. Speed compares against a fixed target or its running average. Average speed and cadence compare against a fixed target or a min/max range with warning bands.
Average speed comes in two variants: Total and Moving. Total includes paused time, useful for ultra-distance events and ACP randonneuring checkpoint speeds. Moving excludes paused time.
A 3- or 4-column HUD groups any combination of fields side by side with per-slot zone coloring. When a route is loaded, an optional Tufte-inspired elevation sparkline sits below the HUD in one of two modes. On shows the whole route's upcoming terrain with non-linear zoom around your current position; tap to cycle 5/10/20 km lookahead. Climbs is a Barberfish take on Hammerhead's Climber: it stays hidden until a climb nears, shows a Climb 2/5 heads-up, then frames the climb foot to summit as you ride up and clears at the top, revealing earlier for harder climbs.
Each palette is shown in three rows. The first two are Text mode against the Karoo cell background, once in light mode and once in dark mode, each using its contrast-tuned variant. The third row is Fill mode: palette color as cell fill with the auto-picked overlay text color, which renders the same in either theme.
| Palette | Power zones | HR zones |
|---|---|---|
| Karoo | ||
| Wahoo | ||
| Zwift | ||
| Intervals.icu | ||
| HSLuv |
| Palette | Grade bands |
|---|---|
| Karoo | |
| Wahoo | |
| Garmin | |
| Zwift | |
| HSLuv | |
| Turbo |
For the APCA contrast and HSLuv tuning behind every palette, see docs/color-palettes.md.
Complete list of data fields provided by Barberfish, grouped by category.
| Data field | Enhancements | |||
|---|---|---|---|---|
| Palette | Threshold | Format | Smoothing | |
| HUD | ||||
| HUD | per-slot | per-slot | per-slot | per-slot |
| Power | ||||
| Power | Zone | Instant / 3s / 5s / 10s / 30s / 20m / 1h | ||
| Avg Power | Zone | |||
| Lap Avg Power | Zone | |||
| Last Lap Avg Power | Zone | |||
| NP | Zone | |||
| Power Zone | Zone | int / float | ||
| Max Power | Zone | |||
| Heart Rate | ||||
| HR | Zone | |||
| Avg HR | Zone | |||
| Lap Avg HR | Zone | |||
| Last Lap Avg HR | Zone | |||
| %Max HR | Zone | |||
| Max HR | Zone | |||
| HR Zone | Zone | int / float | ||
| Speed | ||||
| Speed | Fixed / Avg total / Avg moving | Instant / 3s / 5s / 10s | ||
| Avg Speed (Total) | Fixed / Min-max range | |||
| Avg Speed (Moving) | Fixed / Min-max range | |||
| Cadence | ||||
| Cadence | Fixed / Min-max range | Instant / 3s / 5s / 10s | ||
| Climbing | ||||
| Grade | Grade | OLS (30 m window) | ||
| Elevation sparkline | Grade | |||
| Time | ||||
| Elapsed | Racing / Clock / Segments | |||
| Moving | Racing / Clock / Segments | |||
| Paused | Racing / Clock / Segments | |||
| Lap | Racing / Clock / Segments | |||
| Last Lap | Racing / Clock / Segments | |||
| Navigation & ETA | ||||
| Time to destination | Racing / Clock / Segments | |||
| Remaining ride time | Racing / Clock / Segments | |||
| Time of arrival | ||||
| Daylight | ||||
| Time to sunrise | Racing / Clock / Segments | |||
| Time to sunset | Racing / Clock / Segments | |||
| Time to civil dawn | Racing / Clock / Segments | |||
| Time to civil dusk | Racing / Clock / Segments | |||
| Device | Oldest tested firmware |
|---|---|
| Karoo 3 | 1.618.2377.20 |
| Karoo 2 | 1.613.2351.12 |
Barberfish is expected to keep working on newer Karoo firmware unless Hammerhead introduces breaking changes to the extension SDK.
Light mode and dark mode are both supported, as are metric and imperial units.
- Find the APK link on the latest release page.
- Sideload the APK
- Karoo 3: via the Karoo app following Hammerhead's sideloading instructions.
- Karoo 2: via your computer following DC Rainmaker's instructions
- Gradient-aware forward-looking ETA: see Godot
- Workout target field: continuous deviation from the target (power, HR, pace) with zone coloring reflecting how far off target you are
- karoo-ext: the official Hammerhead SDK for building Karoo extensions
- awesome-karoo: a curated list of Karoo extensions and resources
- Hammerhead Visual Data Field System: the Figma design guide used to match the native Karoo look and feel
Bug reports and pull requests are welcome on GitHub. Suggestions for new HUD data fields are especially welcomed.
BarberfishView and BarberfishDataType are a reimplementation of the native Karoo data field that matches the Hammerhead look and feel, with added support for variable font sizes and control over the fill color behind the label and icon.
See docs/architecture.md for the component hierarchy, naming conventions, and the rationale behind using AndroidRemoteViews for the label and value rendering. See docs/sdk-findings.md for empirically discovered SDK behavior.
Released under the Apache License 2.0.








