Skip to content

Layers & bindings โ€‹

A keymap is a stack of layers, and each layer assigns a binding (an action) to every physical key. Layers share the same geometry and matrix โ€” only the bindings differ.

๐Ÿ“ท Screenshot slot โ€” docs/public/images/builder/layers.png

The Layers panel (layer list with L0/L1 badges) and the binding picker open at the bottom.

Layers panel โ€‹

The Layers section lists every layer with its name and an L{index} badge.

  • Click a layer to select it โ€” the canvas then edits that layer's bindings.
  • Add layer โ€” appends a layer (bindings start transparent / pass-through).
  • The per-layer โ‹ฎ menu has Rename, Duplicate, Delete (Delete is disabled when only one layer remains). Double-click a name to rename inline.

Layer order matters: a transparent binding falls through to the layer below, and bindings reference layers by name (a layer-tap targets "raise", not an index).

json
"layers": [
  { "name": "base",  "bindings": [ /* โ€ฆ */ ] },
  { "name": "lower", "bindings": [ /* โ€ฆ */ ] },
  { "name": "raise", "bindings": [ /* โ€ฆ */ ] }
]

The binding picker โ€‹

Select a key and click Edit binding (or a slot in the inspector) to open the picker. Its header chip shows the context, e.g. base ยท Key #5 ยท A โ€” layer, key index, slot, and current binding. A firmware chip (e.g. QMK + VIA, with a USB/Bluetooth icon) shows which targets the picker is offering actions for; Close picker dismisses it.

The picker is firmware-aware โ€” it only offers actions the selected target(s) support and warns when one is unsupported.

Bindings, in the config โ€‹

Each layer's bindings array has one action per key, in keyboard.keys order. You can write the friendly shorthand and the app expands it:

json
"bindings": [
  "Q", "W", "E", "R", "T",
  { "type": "mod_tap", "tap": "A", "mod": "LEFT_GUI" },
  "Ctrl+C",
  { "type": "layer_tap", "tap": "SPACE", "layer": "raise", "resolve": "prefer-hold" },
  { "type": "transparent" }
]
You assignโ€ฆExamples
A keycode"Q", "SPACE", "Volume Up"
A modified key (combo string)"Ctrl+C", "Ctrl+Shift+4"
Tap-hold presetsmod_tap (hold = modifier), layer_tap (hold = layer)
Layer switch{ "type": "layer", "mode": "momentary", "layer": "lower" }
Specialcaps_word, sticky_key, transparent, none, output, lighting, mouse
Referencesmacro, tap_dance, mod_morph, hold_tap (defined at the top level)

The complete catalog โ€” every action, its fields, and firmware support โ€” is in the Actions reference.

Encoders & sliders โ€‹

A key tagged Encoder carries cw / ccw / press bindings per layer; a Slider carries an analog value-map. You assign these from the inspector. In the config they live on the layer:

json
{
    "name": "base",
    "bindings": [
        /* โ€ฆ */
    ],
    "encoders": [{ "cw": "Volume Up", "ccw": "Volume Down" }]
}

It is all one config โ€‹

Whatever you assign is written into the same JSON config the Edit JSON panel shows โ€” so you can build visually and read the JSON back, or paste a whole layer of bindings and watch the canvas update.

Next โ€‹

Identity & hardware โ†’

Apache-2.0. Originally forked from ZMK Studio; application layer fully rewritten.