carpalx - keyboard layout optimizer - save your carpals
Carpalx optimizes keyboard layouts to create ones that require less effort and significantly reduced carpal strain!

Have ideas? Tell me.

the best layout

Partially optimized QWKRFY and fully optimized QGMLWY layouts are the last word in easier typing.

the worst layout

A fully anti-optimized TNWMLC layout is a joke and a nightmare. It's also the only keyboard layout that has its own fashion line.

download and explore

Download keyboard layouts, or run the code yourself to explore new layouts. Carpalx is licensed under CC BY-NC-SA 4.0.


Download and install the layouts.

Model Parameters

A complete description of the typing model can be found in Carpalx - Typing Effort section. Here I list parameter sets.


The typing effort model is parametrized by the following sets of parameters

  • effort component weights: `k_\text{b}`, `k_\text{p}`, `k_\text{s}`
  • triad interaction parameters: `k_1`, `k_2`, `k_3`
  • penalty weights: `w_0`, `w_\text{h}`, `w_\text{r}`, `w_\text{f}`
  • penalties: `P_\text{h}`, `P_\text{r}`, `P_\text{f}`
  • stroke path weights: `f_\text{r}`, `f_\text{h}`, `f_\text{f}`

For brevity, subscripts for hand, row and finger are shortened to h, r, f (e.g. `f_\text{row} \rightarrow f_\text{r}`). $$ e_i = k_b b_i + k_p p_i + k_s s_i $$ $$b_i = k_1 b_{i1} (1 + k_2 b_{i2} ( 1+ k_3 b_{i3}))$$ $$p_i = k_1 p_{i1} (1 + k_2 p_{i2} ( 1+ k_3 p_{i3}))$$

model name description `k_\text{b,p,s}` `k_{1,2,3}` `w_0`, `w_\text{h,r,f}` `P` `f`
mod_01 balanced contributions 0.3555, 0.6423, 0.4268 1, 0.367, 0.235 penalty_weight_01
0, 1, 1.3088, 2.5948
`P_\text{h}` = 0, 0
`P_\text{r}` = 1.5, 0.5, 0, 1
`P_\text{f}` = 1, 0.5, 0, 0, 0, 0, 0.5, 1
`f_\text{h}` = 1
`f_\text{r}` = 0.3
`f_\text{f}` = 0.3

parameter selection

Since there are many parameters, there is opportunity to define a variety of models, each with a focus on different aspects of typing. For example, one model could have parameters that have no finger penalties whereas another model might heavily penalize the pinky.

I used to have multiple parameter sets listed here, but found that this added too much complexity to the description. Therefore, I will present a single set of parameters and use this set for all layout evaluation and simulation. This parameter set is called mod_01 (i.e. model 01).

The penalty weights (`w_\text{h}, w_\text{r}, w_\text{f}`), effort component weights (`k_\text{b}, k_\text{p}, k_\text{s}`), and triad interaction parameters (`k_1, k_2, k_3`) were selected so that the effort components for QWERTY had specific ratios. The ratios for the model for the base:penalty:stroke effort components is 1:1:1 (fairly easily justifiable — a balanced contribution) and the row and finger component of the penalty also has a ratio of 1:1.

Specifically and first, the hand penalty weight `w_\text{h}` was set arbitrarily to 1 — this value is unimportant since there is no hand penalty (i.e. `P_\text{h = left} = P_\text{h = right} =0`. The row penalty weight, `w_\text{r}`, and finger penalty weight, `w_\text{f}`, were set so that the row- and finger-associated penalties were identical. This can be achieved with any number of parameter pairs (I don't immediately recall why I didn't make one of these 1). Next, the interaction parameters were set so that the ratio of efforts was `(k_1, k_2 = k_3 = 0) : (k_1, k_2, k_3 = 0) : (k_1, k_2, k_3) = 60:30:10`. Arbitrarily, `k_1 = 1`. In other words, the interaction between the second and first key in the triad contributed to 30% of the effort and the interaction between the third and the first two keys contributed 10%. Once these parameters were fixed, the component weights were adjusted so that the base, penalty and path efforts for QWERTY were all 1, making up a total effort of 3.

To make the consequences of the parameter selection process concrete, below is the effort table for QWERTY. Notice that the effort contributions from base, penalty and path are equal. Furthermore, the row and finger components of the penalty are also equal (these penalty components do not mix linearly, and therefore the total penalty is larger than the sum of the components).

QWERTY typing effort - english corpus
model keyboard total effortrel% effort contributionsrel%
base penalties path
mod_01 qwerty 3.000


Penalty Weight Sets

The penalty weights are the `w_0` and `w_\text{h,r,f}` parameters in the equation for key effort. $$p_{ij} = w_0 + w_\text{h} P_{\text{h}_j} + w_\text{r} P_{\text{r}_j} + w_\text{f} P_{\text{f}_j}$$

These weights adjust contribution of baseline, hand, row and finger penalties.

penalty weight name description `w_0` `w_\text{h}` `w_\text{r}` `w_\text{f}`
penalty_weight_01 default penalty weight 0 1 1.3088 2.5948

As described above, the penalty weights were set to balance row and finger contributions. The hand penalty weight value is arbitrary, since no hand penalties are incurred in this parameter set (the hand penalty values were set to 0, so as not to penalize either hand). The row penalties are subjective, and I set them to 1.5 for the digit row, 0.5 for the top row, 0 for the home row and 1 for the bottom row. I consider the bottom row to be less accessible than the top row. Finger penalties were levied at the ring finger, with a value of 0.5, and the pinky, with a value of 1. I consider the pinky to be quite weak (here some may argue that this pinky penalty, which is `2\times` the ring finger penalty, is too high) and intuitively prefer layouts that lay off the pinky, so to speak.

Penalty Sets

The penalty values are `P_\text{h,r,f}` parameters in the equation for key effort. $$p_{ij} = w_0 + w_\text{h} P_{\text{h}_j} + w_\text{r} P_{\text{r}_j} + w_\text{f} P_{\text{f}_j}$$

These values map the value of hand (L,R), row (number, top, home, bottom) and finger (index, middle, ring, index) onto a penalty. A given model will weight each penalty value using the penalty weight parameters.

penalty name description `P_\text{h}` `P_\text{r}` `P_\text{f}`
penalty_01 default penalties
hand `P_\text{h}`
L 0
R 0
row `P_\text{h}`
number 1.5
top 0.5
home 0
bottom 1
finger `\text{h}, P_\text{f}`
index L 0 R 0
middle L 0 R 0
ring L 0.5 R 0.5
pinky L 1 R 1

Stroke Path Sets

The stroke path effort, si, is determined based on the hand, row and finger stroke pattern categories pr,h,f. Stroke path effort is computed by summing efforts associated with each category. $$s_i = \sum_{j \,=\, \text{hand, row, finger}} f_j p_j$$

Each triad is assigned a distinct hand, row and finger stroke category based on the layout of the triad keys. For example, row category 1 (`p_\text{r} = 1`) is associated with a downward row progression with repetition (e.g. rows=top, top, home) for example.

The balanced stroke path (path_01) yield approximately equal hand, row and finger contributions to the stroke path over the English corpus.

stroke path name description `f_\text{h}` `f_\text{r}` `f_\text{f}`
path_01 balanced stroke path 1 0.3 0.3