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 to type. 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.

19 Mar 21 — Added BEAKL 15, Hieamtsr, Colemak Mod-DH and Mtgap 2.0 layouts to the layouts analysis.

15 Mar 21 — Added the Engram layout by Arno Klein to the layouts analysis.

6 Aug 20 — The search for the world’s best keyboard layout by Paul Guerin

4 May 20 — An interview with Bloomberg's Arianne Cohen Splurge on a Better Keyboard, It's Worth It.

25 May 18 — The BBC article Why we can't give up this off way of typing by Tim McDonald discusses the history and persistence of QWERTY and my Carpalx work.

16 Aug 16 — Ergonomic Keyboard Layout Designed for the Filipino Language at AHFE2016 derives layout for Filipino language using Carpalx

18 Apr 16 — Carpalx layouts soon to appear in freedesktop (package xkeyboard-config) and kbd. Thanks to Perry Thompson.

Concurrent Optimization - Parallelizing Layout Search

configuration file : etc/tutorial-04.conf
output : out/tutorials/04


If you have multiple CPUs you can run carpalx multiple times to increase the likelihood of finding the best layout for your parameter set. The only caveat is to set the output file names to unique values for each run, so that concurrent instances of carpalx do not overwrite each others files.

To do this, I usually set a runid parameter in the configuration file to a random string (parsed and evaluated at run-time) and then concatenate this string to all output files.

runid = __join("", map { chr(97+rand(26)) } (0..5))__
keyboard_output = /home/martink/work/carpalx/dev/out/tutorials/04/tmp-__$CONF{runid}__.conf
keyboard_output_show_parameters = current,annealing

If you flank configuration values with "__" (e.g. __2+2__), the string between the __ delimiters will be evaluated before it is assigned to a variable. Thus, runid will be random 6 character string and the value of keyboard_output will have this value embedded. The likelihood of two instances having the same value is negligibly small.

In this example, I ran 100 instances of carpalx. Each instance optimized over 1,000 iterations. It is very important to include the current parameters in the output file so that you can determine the best candidate.


After the runs are done, I have 100 output files of the form tmp-xxxxxx.conf in the output directory.

> cd /home/martink/work/carpalx/dev/out/tutorials/04
> ls
-rw-r--r--  1 martink users 825 Aug 13 17:06 tmp-aedfne.conf
-rw-r--r--  1 martink users 826 Aug 13 17:06 tmp-alxgbj.conf
-rw-r--r--  1 martink users 829 Aug 13 17:06 tmp-bhlypi.conf
-rw-r--r--  1 martink users 827 Aug 13 17:06 tmp-bwukea.conf
-rw-r--r--  1 martink users 825 Aug 13 17:06 tmp-cuovlg.conf
-rw-r--r--  1 martink users 829 Aug 13 17:06 tmp-ddlrja.conf
-rw-r--r--  1 martink users 825 Aug 13 17:06 tmp-dfplfh.conf

To list the solutions with the 5 lowest efforts,

> grep ^effort * | sort -n +2 -3 | head -5
tmp-zjqgub.conf:effort             = 1.69679625336239785
tmp-taefqt.conf:effort             = 1.71535465610664482
tmp-hwlnsw.conf:effort             = 1.72057806732281894
tmp-ezikjb.conf:effort             = 1.72235159706217446
tmp-ejtrhx.conf:effort             = 1.725622120225492

Out of the 100 iterations, final typing efforts range from 1.697 to 2.598. The top layout is in tmp-zjqgub.conf with a final typing effort of 1.697.

z y u l b c d g f q [{ ]} \|
 r i a o h n t e s ;: '"
  x v k p j m w ,< .> /?