QMK Basics: Tap and hold actions: Tap into your modifiers (2023)

New to QMK, or in for a refresher? In this series of tutorials on QMK Basics, you’ll be brought up to speed on a number of features that help you customize your keyboard just the way you want it.

When fitting in your keymap onto a smaller keyboard than you’re used to, finding enough keys can be difficult. Even if you’ve got plenty of keys at your disposal, making some often used keys more accessible can provide you with more comfort and efficiency.

The QMK framework offers some creative ways to use your modifier keys so that they’re not just modifiers, but also a key of your choosing.

When is the last time you tapped a modifier key like Control, Shift or Alt? Modifier keys are often used in conjunction with another key, so you’ll often hold the key instead of tapping it. With the various keycodes I’ll describe below, you can put those modifier keys to use.

Table of Contents

(Video) QMK tap dancing and one-shot layers quick demo


To quote the documentation:

The Mod-Tap keyMT(mod, kc)acts like a modifier when held, and like a regular keycode when tapped. In other words, you can have a key that sends Escape when you tap it, but functions as a Control or Shift key when you hold it down.

Advanced Keycodes documentation, section Mod-Tap

There are many shortcuts available for the MTkeycode that are configured with the right modifier, so you’ll only need to pick the keycode you want. Some of those keycodes are LCTL_T(kc), which is Left Control when held and sends kcwhen tapped.

Limitations of Mod-tap

Shifted keycodeswon’t work. They are keycodes that send, for example, a #by themselves instead of having to press SHIFT + 3. Mod-tap ignores modifiers sent with the keycode, so MT(MOD_LSFT,KC_HASH)would send a 3when pressed instead of a #.

The keycodes MT(mod, kc)and LT(layer, kc)only support basic keycodes.

QMK collaborator Drashna in response to the question “Programming mod tap keys for shifted keycodes“, 2018-06-05.

Here is some background to this issue:a pull request by dpapavasand this thread by Fin_Complete on Reddit.

There also isn’t a way to execute custom functions with Mod-Tap. The Mod-tap function directly registers the keycode with register_code, and doesn’t call process_record_user.

(Video) QMK Tutorial: Keymap Creation Tips

A workaround for mod-tap

MechMerlin shared a very interesting code snippet in which he emulates the mod-tap behavior, adding the ability to perform custom functions. He makes various videos on keyboards and adventures with them at his YouTube channel.

We can emulate a mod-tap action by manually keeping track of whether a key was tapped or held in the process_record_userfunction. In this example, let’s send the shifted key # manually, something that mod-tap can’t do for us.

  1. You can add #define TAPPING_TERM 200to your config.h. Any tap that’s shorter than 200ms will be a tap, anything longer will be held. You can pick a duration of your choice, 200 is the default.
  2. Define a custom keycode by adding the custom_keycodesarray. Our keycode will be named MY_HASH.
  3. Place the custom keycode somewhere in your keymap. In this example, we only have a single key, so deciding where to put it is easy.
  4. Now to edit the process_record_userfunction. First, add a variable to hold a timer value in. We make it static so the value is saved over time: normally, when a function like this is over, all the variables are emptied. This time, we want to remember at what time MY_HASHwas pressed, so staticremembers the value for us.
  5. Add the belowswitchstatement. You may already have such a switch statement, if so, you can place a new case in the existing statement.
  6. When MY_HASH is pressed, we log the time to the my_hash_timervariable. We also register the keycode KC_LCTL, you can replace this with your held modifier of choice. This means that the modifier is in effect the moment you press the key.
  7. When MY_HASHis released, we unregister KC_LCTL, so the modifier won’t be active anymore. Then, we check the timer: if it’s smaller than TAPPING_TERM, it’s a tap action and we will send the character we want: #. Instead of using TAPPING_TERM, you can enter a duration in milliseconds, anything below it will be a tap, anything more will be held.
#include QMK_KEYBOARD_Henum custom_keycodes { MY_HASH = SAFE_RANGE};const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = LAYOUT( /* Base */ MY_HASH \ ),};bool process_record_user(uint16_t keycode, keyrecord_t *record) { static uint16_t my_hash_timer; switch (keycode) { case MY_HASH: if(record->event.pressed) { my_hash_timer = timer_read(); register_code(KC_LCTL); // Change the key to be held here } else { unregister_code(KC_LCTL); // Change the key that was held here, too! if (timer_elapsed(my_hash_timer) < TAPPING_TERM) { SEND_STRING("#"); // Change the character(s) to be sent on tap here } } return false; // We handled this keypress } return true; // We didn't handle other keypresses}

Space cadet

QMK has two features that are very much alike Mod-tap:Space Cadet ShiftandSpace Cadet Shift Enter. These features are much like Mod-tap, but have the ability to send specific shifted keycodes.

Space Cadet Shift sends(when the left shift is tapped, and )when the right shift is tapped. When the shift keys are held, they’re simply shift. The Space Cadet shift keys have the keycodes KC_LSPOand KC_RSPCfor left and right shift respectively.

Space Cadet Shift Enter acts as a shift key when held and sends Enterwhen tapped. Its keycode is KC_SFTENT.

Both Space Cadet Shift and Space Cadet Shift Enter conflict with the Command feature, since they all use the same timer. If you decide to use the keycodes for Space Cadet, disable Command by adding COMMAND_ENABLE = noto your rules.mk.

Layer keys

Like MT(mod, kc), there exists a key to enter a layer when held, but which sends a keycode when tapped: LT(layer, kc). LT(layer, kc) activates layer momentarily when held, and sends the given keycode when pressed.

(Video) QMK Tutorial: QMK Configurator

It has the same limitations as MT(mod, kc): it only supports basic keycodes, so no shifted keys and no user functions.

Customizing the tapping term

Under Behaviors that can be configured, there’s an interesting entry: #define TAPPING_TERM 200. The tapping term defines for how long in milliseconds you need to hold a key before the tap becomes a hold.

You can add the above line to your config.h.


There are many ways people use Mod-tap and Space Cadet. Some of those ways aren’t as obvious when starting out, but you may end up liking them in your keymap. Here are some examples of how people use tap and hold actions.

Home-row modifiers

In the thread What are your favorite QMK hacks?, user Canatella explains how to use mod-tap for home-row modifier keys. Canatella didn’t post a keymap, but here’s a possible application:

QMK Basics: Tap and hold actions: Tap into your modifiers (1)

You can accomplish the above with the following keycodes, from left to right:

  • MOD_LGUI(KC_A)for the left Windows/Command/Meta key;
  • MOD_LALT(KC_S)for the left alt key;
  • MOD_LCTL(KC_D) for the left control key;
  • MOD_LSFT(KC_F)for the left shift key;
  • LT(LOWER, KC_G)for the lower layer key.

Check out the Mod-Tap documentation for more keycodes.

(Video) How I flash my Vial Keyboards - QMK Layer Indicator

Doubling up on thumb-keys

Kauyon Kais has shared his custom keyboard build, which makes use of a number of featurs, including tap and hold modifiers. In his keymap, you can find the full source code.

QMK Basics: Tap and hold actions: Tap into your modifiers (2)

Here are some of the keycodes used to make the tap and hold keys work:

  • MT(MOD_LSFT, KC_BSPC)for backspace on tap and shift on hold;
  • LT(_FUN, KC_ENT)for enter on tap and switching to the _FUNlayer on hold;
  • LT(_SYB, KC_SPC)for space on tap and switching to the _SYB layer on hold.

Reusing some often used keys like shift, enter and space is a very clever way to regain some key estate. It also places more emphasis on the thumbs. Thumbs are generally stronger than the outer fingers, which should provide more comfort.

QMK Basics: Tap and hold actions: Tap into your modifiers (3)


You can put your modifier and layer keys to use by also assigning a tap action to them. This also works the other way around: You can make ordinary keys function as a modifier or layer key when held.

Just know that only basic keycodes are supported for tap and hold keys. That’s still a rather long list, so there are plenty of possibilities to explore!

Further reading

There are more ways than #define TAPPING_TERM 200 to configure the way QMK handles your tap and hold keys:

  • Permissive hold: Makes tap and hold keys work better for fast typists, or when you’ve set TAPPING_TERMto a high value.
  • Ignore Mod Tap Interrupt: Alters the behaviour of tap and hold keys in a similar but different way than Permissive hold.
  • Tapping Force Hold: Allows you to have the given keycode repeat when tapping and then holding the modifier key for a second time.
  • Retro Tapping: Sends the keycode instead of the modifier when you have held the modifier without pressing another key.

New to QMK, or in for a refresher? In this series of tutorials on QMK Basics, you’ll be brought up to speed on a number of features that help you customize your keyboard just the way you want it.

(Video) Writing QMK macros


What is mod tap on a keyboard? ›

The Mod-Tap key MT(mod, kc) acts like a modifier when held, and a regular keycode when tapped. In other words, you can have a key that sends Escape when you tap it, but functions as a Control or Shift key when you hold it down. The modifiers this keycode and OSM() accept are prefixed with MOD_ , not KC_ : Modifier.

What is tap dance QMK? ›

Tap Dance is a powerful feature in QMK that lets a key do something else when pressed more than once.

What are layers in QMK? ›

One of the most powerful and well used features of QMK Firmware is the ability to use layers. For most people, this amounts to a function key that allows for different keys, much like what you would see on a laptop or tablet keyboard. For a detailed explanation of how the layer stack works, checkout Keymap Overview.

Does QMK support per key RGB? ›

RGB matrix is a QMK lighting mode suitable for implementing per-key RGB lighting as well as a combination of per-key RGB and underglow. It is the recommended lighting mode for most purposes.

How do you type home row keys? ›

Learn How To Type The Home Row Keys - YouTube

What does QMK stand for? ›

Quantum Mechanical Keyboard Firmware

QMK (Quantum Mechanical Keyboard) is an open source community centered around developing computer input devices.

What programming language is QMK? ›

A low-level programming language suitable for system code. Most QMK code is written in C.

How do I configure my QMK keyboard? ›

QMK Tutorial: QMK Configurator - YouTube


1. How to have 10 Keyboards in One | Understanding Layers
(Dygma Lab)
2. EVERY DaVinci Resolve SPEED EDITOR Modifier Key Explained - Tutorial
(Creative Video Tips)
3. QMK Made EASY! (Adding QMK To My DIY Arduino Keypad)
(John Mad Labs)
4. Making a keymap using a QMK configurator
5. QMK Firmware Tutorial: Macro Basics (Part 6)
6. Make your keyboard better with KMonad | حسن الكيبورد بتاعتك
Top Articles
Latest Posts
Article information

Author: Sen. Emmett Berge

Last Updated: 03/07/2023

Views: 6285

Rating: 5 / 5 (80 voted)

Reviews: 95% of readers found this page helpful

Author information

Name: Sen. Emmett Berge

Birthday: 1993-06-17

Address: 787 Elvis Divide, Port Brice, OH 24507-6802

Phone: +9779049645255

Job: Senior Healthcare Specialist

Hobby: Cycling, Model building, Kitesurfing, Origami, Lapidary, Dance, Basketball

Introduction: My name is Sen. Emmett Berge, I am a funny, vast, charming, courageous, enthusiastic, jolly, famous person who loves writing and wants to share my knowledge and understanding with you.