Why home‑row mods felt flaky—and what changed in 2025
If you’ve tried home‑row mods (HRMs) with mod‑tap keys, you’ve probably hit the same wall: rolled letters on one hand unexpectedly trigger modifiers. In February 2025, QMK added Chordal Hold to core, and it’s the first fix that reliably makes dual‑function keys behave for everyday typing. By default, Chordal Hold applies an “opposite‑hands” rule: when a mod‑tap is pressed and another key is pressed within the tapping term, the mod‑tap is forced to tap if that other key is on the same hand—preventing accidental modifiers during one‑hand rolls. (docs.qmk.fm)
Compared with the popular Achordion userspace library, Chordal Hold is built into QMK, integrates directly with tap‑hold logic (less buffering/lag), and is easier to configure. Achordion’s author even describes Chordal Hold as the newer, better version in core. (reddit.com)
The short version: what to enable
- In QMK: enable CHORDAL_HOLD and pair it with either Permissive Hold or Hold On Other Key Press. Many users set TAPPING_TERM around 220–250 ms for HRMs. (docs.qmk.fm)
- 2025 additions you can layer on:
- Flow Tap (May 25, 2025): disables tap‑hold “hold” behavior during fast typing bursts and sends taps immediately—great for HRMs. (docs.qmk.fm)
- Speculative Hold (Nov 30, 2025): applies the modifier instantly on keydown and cancels if it becomes a tap—handy for Shift+click / Ctrl+scroll without lag. (docs.qmk.fm)
QMK setup (code you can drop in)
Add to your config.h:
```c
// Core tap-hold tuning
#define TAPPING_TERM 240
#define PERMISSIVE_HOLD
// New in 2025
#define CHORDAL_HOLD // settle same-hand chords as taps
#define FLOW_TAP_TERM 150 // optional: "flow of taps" during fast typing
```
In keymap.c, tell QMK which keys are left, right, or exempt. Mark thumbs with '*' if you want them excluded from Chordal Hold:
```c
// Example for a 4x12 split; adapt to your matrix
char chordal_hold_layout[MATRIX_ROWS][MATRIX_COLS] = {
// 'L' = left hand, 'R' = right hand, '*' = exempt (e.g., thumb keys)
{ 'L','L','L','L','L','L', 'R','R','R','R','R','R' },
{ 'L','L','L','L','L','L', 'R','R','R','R','R','R' },
{ 'L','L','L','L','L','L', 'R','R','R','R','R','R' },
{ '','','','','','', '','','','','','' }, // thumbs exempt
};
```
Need exceptions? Allow a same‑hand hotkey (e.g., Ctrl‑Z with C/V) via the per‑chord callback:
```c
bool get_chordal_hold(uint16_t tap_hold_keycode, keyrecord_t* tap_hold_rec,
uint16_t other_keycode, keyrecord_t* other_rec) {
switch (tap_hold_keycode) {
case LCTL_T(KC_Z):
if (other_keycode == KC_C || other_keycode == KC_V) return true; // allow hold
break;
}
return get_chordal_hold_default(tap_hold_rec, other_rec);
}
```
Chordal Hold acts only within the tapping term and operates on mod‑tap (MT) and layer‑tap (LT) keys. Watch out for matrix irregularities around big keys and thumb clusters—verify handedness against your physical layout. (docs.qmk.fm)
Oryx (ZSA) recipe
- Open Oryx and head to Settings → Holding → Chordal Hold; toggle it on. As of June 2025, Oryx excludes thumb keys from Chordal Hold by default because it feels more natural for layers/mods on thumbs—keep this unless you have a reason to change it. (blog.zsa.io)
- You can still fine‑tune tapping term, and combine with Permissive Hold. ZSA’s write‑up frames Chordal Hold as the new, simpler recommendation for dual‑function keys. (blog.zsa.io)
Vial and VIA
- Vial: Version 0.7.4 (July 12, 2025) adds UI toggles for Chordal Hold and Flow Tap under QMK Settings → Tap‑Hold. If you like experimenting without reflashing each tweak, this is the easiest path. (get.vial.today)
- VIA: VIA can send MT/LT keycodes and even “ANY” QMK codes, but it doesn’t expose a dedicated Chordal Hold toggle. To use Chordal Hold you’ll compile firmware with CHORDAL_HOLD (and then VIA can still edit your keymap). The “ANY key” approach helps you set up MT/LT in VIA if you’re not compiling yet. (en.akkogear.com)
Achordion vs. Chordal Hold (should you migrate?)
Achordion pioneered the idea: decide “tap vs. hold” based on what you chord next, often using an opposite‑hands rule and optional timeouts. In 2025, Chordal Hold superseded it in QMK core with cleaner integration and less perceived delay. Achordion’s own page points to Chordal Hold as the way forward; migrate by enabling CHORDAL_HOLD and using the handedness array or per‑chord callback. (getreuer.info)
Pitfalls and pro tips
- Thumb‑key exceptions: Many boards wire thumbs oddly relative to the alpha cluster, so mark thumb positions as '*' to exempt them—or rely on Oryx’s “exclude thumbs” default. This avoids breaking layer switches on your thumbs. (docs.qmk.fm)
- Combos: Chordal Hold’s handedness is ill‑defined for multi‑key combos; combos are exempt by default but still adjustable via callback if needed. (docs.qmk.fm)
- Vim on QWERTY: HRMs on J/K/L can feel awkward for hjkl navigation. Consider bottom‑row mods, Repeat Key, or different nav strategies if this bothers you. (reddit.com)
- Flow Tap priority: Flow Tap and Chordal Hold play well together; Flow Tap generally takes precedence during rapid taps, further reducing accidental holds. (reddit.com)
A/B test it: measure WPM and accuracy vs. your baseline
Here’s a simple protocol you can run on a 1‑minute typing test (repeat each condition 3 times, use the median):
1) Baseline: regular layout, no HRMs.
2) HRMs with only Permissive Hold and a sane TAPPING_TERM (e.g., 220–250 ms).
3) HRMs + Chordal Hold.
4) HRMs + Chordal Hold + Flow Tap (e.g., FLOW_TAP_TERM 150).
Track net WPM and accuracy. Typical patterns reported in the community: some typists see immediate accuracy gains with HRMs + Chordal Hold (fewer misfires), others need practice, and a few note a small top‑speed reduction at first (e.g., ~15 WPM at peak) that may diminish as muscle memory adapts. Use your data to decide—comfort and accuracy beat peak bursts for long coding/writing sessions. (reddit.com)
Copy‑paste starting points
- Minimal HRM‑friendly stack in 2025: CHORDAL_HOLD + PERMISSIVE_HOLD, TAPPING_TERM 240, optionally FLOW_TAP_TERM 150. (docs.qmk.fm)
- Per‑key tuning: keep TAPPING_TERM_PER_KEY for especially twitchy letters; raise for pinkies, lower for index‑heavy mods. Achordion’s guidance put many typists in the 160–220 ms range; Chordal Hold tends to work well slightly higher (≈220–250 ms). (getreuer.info)
The bottom line
If HRMs felt fragile before, try again. With Chordal Hold in QMK master (Feb 2025), plus Flow Tap and Speculative Hold later in the year, dual‑function keys finally feel predictable at speed—without sacrificing the shortcuts that make them worth it. Enable it, add a few thumb/one‑hand exceptions, and validate the gains with a quick A/B on your favorite typing test. (docs.qmk.fm)