Releases: BenjiPy/hevy-ranks
Release list
v0.4.0-pre1 — Glassmorphism UI (pre-release)
Pre-release. The full glass UI overhaul with every v0.3.2 feature and v0.3.1 hotfix baked in. Ranks logic unchanged — this is a visual pre-release. Expect the frosted look to gracefully fall back on browsers without
backdrop-filter(text stays readable, glass feel is lost).
What's new visually
- Frosted-glass everywhere. Panels, cards, dropdowns, inputs, toasts, tooltips, badges and tables are now translucent surfaces with real
backdrop-filterblur, thin luminous borders, and an inset top highlight that catches "light" like a real pane. - Ambient background. Four drifting colored radial blobs (blue / purple / cyan / pink) give the blur something rich to work on. Drift disabled automatically on
prefers-reduced-motion. - Bluish-purple CTAs. Primary buttons get a gradient fill with a colored ambient shadow.
- Logo on a glass chip. The v0.3.2 shield SVG now sits inside a soft glass chip in the header.
- Share modal upgraded. The share-as-image modal (v0.3.2) is migrated to the glass tokens: card, backdrop, preview frame and format/mode/theme pills.
Carried over from v0.3.2 and v0.3.1
- Share as PNG (3 formats × 3 themes × 3 modes) with native Web Share on mobile and Copy image on desktop.
- Dedicated "Your data" privacy page.
- "Hide my bodyweight" toggle in the share modal.
- Results + raw compute data persisted in
sessionStorageso the share button works after a hard refresh. - Multilingual catalog (EN/FR/ES/DE/PT/IT) and assisted-machine bodyweight sign hotfix.
Known limitations (pre-release)
- Older browsers without
backdrop-filtersupport only get the progressive-enhancement fallback (readable, but the frosted feel is lost). Wider fallback polish lands before v0.4.0 stable. - No engine or logic change — no impact on your calculated ranks.
Full changelog: CHANGELOG.md
v0.3.2 — Share your ranks
The v0.3 finale. Three community-driven features + a proper coat of paint.
What's new
- Share your ranks as PNG. New "Share with your friends" button on the results page opens a modal with a live preview. Pick your format (square for Instagram, 9:16 for stories, 16:9 for Twitter/desktop), theme (Midnight / Daylight / Vaporwave), and content mode (best rank only / all groups grid / all groups + details). On mobile, drop straight into Instagram / Discord / X via the native share sheet; on desktop, copy the image to your clipboard. Nothing leaves your device — the PNG is rendered locally in your browser.
- Hide my bodyweight. Optional toggle in the share modal for users who want to flex their rank without revealing kg.
- Dedicated "Your data" page. Full breakdown of what happens to your data per mode (CSV / API-key), what's stored in the browser, which third parties are involved, and how to wipe everything. Reachable from the header, the footer, and both setup panels.
- New logo & favicon. Custom SVG (shield + chevron + barbell) replaces the plain "HR" square. Same asset serves as favicon, Apple touch icon and header brand mark, plus a
theme-colorfor mobile browser chrome.
Fixes
- Share button now survives a hard refresh (results and compute output persisted in sessionStorage).
- Export layout is finally bulletproof: auto-fit on the Hero card, dedicated side-by-side layout for landscape, cell-height-capped font scaling for Grid/Detail — nothing bleeds into the footer anymore.
- Fixed a rendering artifact where decimal font sizes tripped the tier-badge regex and drew a giant orange band down the middle of the canvas.
- Light theme reworked so the export card actually shows against the background.
Coming next
v0.4.0 will focus on a full glassmorphism UI overhaul.
Full changelog: CHANGELOG.md
v0.3.1 — Assisted-machine sign fix & non-English CSV coverage
Two related hotfixes from community feedback on v0.3.0. No breaking
change, no engine architecture change — mostly non-English users
benefit.
🐞 Bug fix — assisted-machine sign
Assisted pull-ups, chin-ups and dips (Assisted / Assistée /
Band / equivalents in FR / ES / DE / PT / IT) were treated as
added weight instead of subtracted when the CSV title didn't
exactly match the English template catalog. Result:
more assistance = higher Back / Chest score, which is obviously
backwards.
The engine now detects assisted / weighted bodyweight variants
directly from the title using a multilingual keyword list, and
overrides the load semantics accordingly. Assistance that meets or
exceeds bodyweight now correctly skips the set (was silently
producing 0 before).
Big thanks to the Reddit user who caught this — it's exactly the
kind of feedback that makes the project mature.
🌍 Non-English CSV coverage (ES + DE + PT + IT)
Hevy's exercise catalog is English-only, so users on other Hevy
locales were bleeding accuracy in three places. All three are now
fixed:
- Muscle group inference (
GROUP_HINTS): Spanish, German,
Portuguese and Italian keywords added across all groups and the
cardio/mobility skip list. 36 multilingual test cases pass. - Per-exercise coefficients (
GROUP_COEFFS): same
multilingual pass on the coefficient table, so aPrensa/
Beinpresse/Pressa Gambepicks up the leg-press coefficient
(3.0) instead of falling through to the group default (which was
over-crediting foreign users on machine-friendly lifts). - Fuzzy catalog lookup:
buildCatalog()now indexes each
template by a canonical form (sorted tokens, parens stripped)
so titles likeBarbell Bench Pressmatch
Bench Press (Barbell), and so on.
🇩🇪 German compound words
matchesWord() now allows a trailing compound tail for single-word
needles of ≥ 5 chars, so Bankdrucken / Bizepscurl /
Schulterdrucken match their base keywords (bank, bizeps,
schulter). Multi-word needles stay strict.
🧹 Also
corda(PT/IT jump rope keyword) no longer incorrectly skips
triceps rope pushdowns.- Many missing EN/FR variants added (
Meadows Row,
Landmine Press,Belt Squat,Muscle Up,Cable Crossover,
Farmer Carry,Ab Wheel,Sissy Squat,Pallof Press, etc.). bodyweightFraction()extended to cover FR/ES/DE/PT/IT variants
of pull-up / squat / push-up so bodyweight-only sets stay
scorable across languages.
Upgrade notes
Existing users' ranks are essentially unchanged — the ranking
engine, coefficients and thresholds are the same as v0.3.0.
Non-English users will see more accurate ranks (previously
over-inflated on assisted work and machine-friendly foreign
titles). No action required.
Full changelog
See CHANGELOG.md.
v0.3.0 — Polished UX, iOS CSV fix, non-English support & actionable recommendations
First stable release of the v0.3 line. Big UX pass across the whole
app, a critical iOS Safari fix, first-class support for non-English
Hevy exports, and actionable per-group recommendations that tell you
exactly what it takes to reach the next rank.
Ranking engine, coefficients and thresholds are unchanged from v0.2
— existing users' ranks won't move.
Highlights
🎨 Polished UX
- Canvas-based confetti burst on results reveal, colored from your
top rank's palette. - Animated rank-parade loader while your CSV / API data is
crunched. - Custom styled rank tooltip on emblems with per-tier colored glow
— no more raw browser tooltip.
📱 iOS Safari CSV fix
- Overlay input pattern so the native picker actually returns the
selected file (previoushidden/clip-rectapproach was silently
broken on iOS). - Explicit UTF-8 read with BOM strip — accented FR exercise names
no longer become mojibake. - Widened MIME accept list for iOS quirks
(text/csv, text/plain, application/vnd.ms-excel, application/octet-stream). - Client-side validation — extension, MIME, size and empty checks
with a clear inline error and no silent fails.
🌍 Non-English CSV support
- Bilingual FR + EN keyword fallback in
inferGroupFromTitlewhen
the exact English catalog misses (regex word-boundary matching,
plural/gender variations covered). - Locale notice on the results page: when many exercises were
matched by keyword instead of the exact English catalog, a
contextual hint suggests switching Hevy to English or using API-key
mode. - README callout for non-English users, plus a tip on the CSV import
panel itself.
🎯 Actionable next-tier recommendations
Per muscle group, we now spell out exactly what it takes to reach the
next rank:
- Compact
↑ +X kg on [Lift]chip on the row (visible without opening
the accordion). - Full
🎯 To reach [Next Tier]panel in the detail view, giving both
the 1RM delta and the equivalent for the user's typical rep range on
their top compound. - Caveat kicks in when the required jump exceeds 30% of the current
1RM, nudging toward balanced progression across other compounds
instead of chasing a single lift. - Max-rank groups get a celebratory 👑 variant; capped groups keep the
existing capped-tip guidance.
🔑 API-key mode reliability hint
- Secondary tip on the CSV import panel and extended locale notice on
the results page both nudge users toward API-key mode (Hevy Pro) as
the precision-perfect option — it uses Hevy's stable exercise IDs,
so there's no title-matching ambiguity regardless of the Hevy app's
language. - Inline links jump straight to the API-key setup view.
🧹 Internals
- Fully English codebase — remaining French comments and CLI strings
translated. - Engine
hasDatahardening (eqRatio != nullrequired). - Cardio / mobility exercises now properly filtered from strength
ranking via aSTRENGTH_TYPESallow-list. - New engine helpers exported:
nextTierRecommendation()and
weightForReps()(reverse Epley).
Upgrade notes
No action required — bring your CSV or API key as before. Ranks are
identical to v0.2; only the presentation, the file handling and the
new recommendations panel change.
Full changelog
See CHANGELOG.md.
v0.3.0-pre1 — Polished UI, animated loader, results confetti, iOS CSV fix & non-English support (pre-release)
Pre-release — big UX pass and two critical fixes (iOS CSV picker,
non-English exports). Up for testing before the stable v0.3.0.
Please try it on your setup and report anything odd on
GitHub issues.
The ranking engine, coefficients and thresholds are unchanged
from v0.2 — your ranks won't move.
Highlights
🎉 Results reveal
Fresh dashboards now land with a confetti burst colored from your
top rank's palette. Fires only on real computations (not on F5 or
when you click Back to your results).
⏳ Rank-parade loader
The plain spinner is gone. The 9 rank emblems now light up in
sequence, each glowing in its own color, giving a "climb the
ladder" feel while your data is crunched. Step messages
("Loading workouts… 3/12", "Parsing CSV…") still show on top.
✨ Landing hover
- Custom styled tooltip on the rank emblems (colored border per
rank, smooth fade) — no more ugly native browser tooltip. - Emblems now lift + glow in their own color on hover.
Critical fixes
📱 iOS Safari — CSV picker
Two combined bugs prevented iPhone users from importing a CSV at all.
- The picker used to open, the file could be selected, and nothing
ever registered in the app. Rewritten with the canonical iOS-safe
overlay input pattern. - The CSV was sometimes greyed out in the iOS Files picker (Hevy's
export is served astext/plain/application/octet-stream).
Widened theacceptfilter accordingly.
🌍 Non-English CSV exports
Hevy's exercise catalog is English-only, so exporting from a French
(or Spanish, German, Portuguese, …) Hevy app used to produce empty
ranks — the app only recognized ASCII-named exercises (typically
Core). Two things fixed this:
- UTF-8 read —
FileReaderwas silently decoding iOS CSVs as
Windows-1252, turning accented titles into mojibake. - FR + EN title fallback — when a title isn't in the English
catalog, the engine now infers the muscle group from a curated
bilingual keyword list (~95 % coverage on standard exercises).
Verified end-to-end on a real French export: all 6 groups populate.
A discreet notice on the results page tells users when many
exercises were routed via the fallback, and the CSV import panel now
carries an upfront tip recommending switching Hevy to English for a
strictly perfect mapping.
Under the hood
- CSV validation — files are checked client-side for
extension / MIME / size (< 20 MB) / non-emptiness before hitting
the parser; bad files surface a clear toast instead of failing
deep inside. computeRanksreturn now includes
matchStats: { catalog, inferred, total }so the UI can decide
when to surface the locale notice.hasDatahardening — a group with lifts but no computable
eqRatio (e.g. missing bodyweight) is now correctlyhasData: false.- Confetti no longer suppressed by
prefers-reduced-motion.
A single-shot, ~4 s, non-strobing, pointer-events-none decorative
reveal doesn't meet the criteria the preference is designed to
guard against. The looping rank-parade loader still honors it.
Docs & codebase
- README header shows all 9 rank emblems (Bronze → Mythic).
- Roadmap restructured into a proper TODO (Done / Planned /
Ideas / Ongoing), including new items (sub-tiers, actionable
recommendations, interactive rank legend, API-mode reliability
hint). - Entire codebase is in English (comments, CLI, error messages).
French keywords used to map Hevy exercise titles in French are
kept intentionally.
🧪 Why pre-release?
The iOS overlay-input pattern and the FR/EN inference are the
canonical solutions for their respective problems, but real-world
iOS can still surprise. If the picker still misbehaves on your
device — please report it and include:
- iOS version
- Where the CSV comes from (Hevy iOS share, iCloud Drive, Files,
Google Drive, other) - Any error toast shown
Next
Once feedback confirms iOS + non-English exports are happy on real
devices, a stable v0.3.0 ships with identical changes (no
-pre1 suffix). Full details:
CHANGELOG.md.
v0.2.2 — README polish + fully English codebase
Small maintenance release on top of v0.2.1. No behavior change.
Docs
- README header now shows all 9 rank emblems (Bronze → Mythic)
instead of a curated subset of 5. - The Roadmap is now a structured TODO with four buckets
(Done / Planned / Ideas / Ongoing) — easier to see what's shipped
and what's coming next.
Codebase cleanup
- CLI (
src/index.js) fully translated to English, including number
formatting (en-US). - All remaining French comments and messages translated across the
engine, CSV parser, Hevy client, env loader, catalog script, and
the web app. - Engine
GROUPSlabels and reference lifts translated to English
(Jambes → Legs, Pectoraux → Chest, Dos → Back, Épaules → Shoulders,
Bras → Arms, Abdos → Core). - French keywords inside
GROUP_COEFFSare intentionally kept so
French-locale Hevy exercise titles keep matching.
Under the hood
- No engine, ranking, or UI behavior changes — everything computed
the same way as v0.2.1.
Full details in CHANGELOG.md.
v0.2.1 — Engine safety fix
Small patch fixing a crash risk when the engine is invoked without a
bodyweight.
Fixed
- Engine:
hasDataincorrectly returnedtruewhen bodyweight was
missing, which could crash consumers readinggroup.tier.name.
v0.2.0 — Composite scoring, isolation guard, and dashboard overhaul
First community-driven release. Addresses the main feedback from the
initial r/Hevy post: isolation lifts crowning entire muscle groups,
Mythic being too easy to reach, and one-off demo sets outranking real
training.
Ranking engine
- Composite scoring. A muscle group's rank is now a weighted average
of your top 3 compound lifts (weights1.0 / 0.5 / 0.25), instead of
a single best lift. One PR alone can no longer carry the whole group. - Isolation exercises are demoted. Calf press, back extension /
hyperextension, pec deck / flyes, shrugs, lateral raises, most curls
and triceps extensions are flagged as isolation and no longer count
when a compound is available. Fallback to isolation is allowed but
the rank is capped at Titan. - Minimum 3 sessions per exercise. A movement needs at least 3
distinct training days to contribute. Fixes the classic "I did pec
deck twice for a friend and it beat my bench" case. If no exercise
in a group reaches 3 sessions, we still use what's there but cap the
rank at Platinum so the group is never empty when there's data. - Rebalanced coefficients. Notably: calf press 1.3 → 2.8, pec deck
0.5 → 0.8, shrugs 1.6 → 1.9, triceps pushdown 1.6 → 1.9, leg extension
0.7 → 0.9, lateral raise 0.35 → 0.5. New entries for back extension /
hyperextension and abductors. - Top thresholds spread out so Mythic actually stays rare
(e.g. Legs Mythic 2.5× → 3.0× bodyweight). Bronze / Iron / Gold
unchanged — beginners aren't penalized. - Cardio and mobility exercises silently filtered from the results.
Dashboard
- Group rows now show only name, tier and progress. Click a group to
open a panel with the composite explanation, the lifts used, and the
lifts excluded (with reason badges). - New "Exercises not counted" section listing unrecognized strength
lifts (cardio filtered out). - Footer with app version + links to Changelog and the GitHub repo.
- Fixed the header "GitHub" link.
- The accordion state, current view and results all survive navigation
and page reloads.
CLI
- Outputs the composite ratio + the top contributing lift, with a
*
marker when the rank is capped by a fallback.
Docs
- README and in-app "How it works" page rewritten to match the new
composite logic and describe the guardrails. - Full changelog available in CHANGELOG.md.
Not affiliated with Hevy. Ranks are estimates, still tunable. Bug
reports, feedback and PRs very welcome.