Skip to content

Firmware targets

Remappr compiles one config to several firmwares. There are three compiler targetszmk, qmk, keychron — and the builder's selectable firmware idszmk, qmk, via, vial — where VIA and Vial both build through the QMK family.

Targets

Builder idCompiles viaOutputWireless
ZMKzmkdevicetree .keymap + .overlay
QMKqmkkeymap.c + keyboard.json
VIAqmk (+ VIA def)QMK + via/<kb>.json
Vialqmk (+ Vial def)QMK + vial.json + UID/unlock config.h
KeychronkeychronVIA/QMK stack + BLE radio

The exact files each target emits are listed in Export, build & flash.

Output examples

The same demo layer compiled to each target.

ZMK .keymap (devicetree):

c
compatible = "zmk,keymap";
base {
    bindings = <
        &kp Q       &kp W   &kp E
        &mt LSHFT A             // home-row mod (mod_tap)
        &lt 1 SPACE            // layer-tap
        &mo 2                  // momentary layer
        &kp LC(C)             // "Ctrl+C"
        &bt BT_SEL 0          // bluetooth profile
        &rgb_ug RGB_TOG      // underglow toggle
    >;
};

Macros, tap-dances and combos become zmk,behavior-macro / zmk,behavior-tap-dance / combo_<name> nodes; encoders use &inc_dec_kp. A tap-hold with a timing/flavor emits a dedicated node (flavor = "hold-preferred").

ZMK .overlay — the physical layout + matrix-transform:

c
#include <physical_layouts.dtsi>
compatible = "zmk,physical-layout";       // key_physical_attrs per key
#include <dt-bindings/zmk/matrix_transform.h>
compatible = "zmk,matrix-transform";       // one RC(r,c) per key, in keymap order
transform = <&default_transform>;

Board hardware you didn't supply (kscan, pinctrl) appears as a /* NOT GENERATED by remappr */ checklist.

QMK keymap.c:

c
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  [0] = LAYOUT( KC_Q, KC_W, KC_E,
                LSFT_T(KC_A),   // mod_tap
                LT(1, KC_SPC),  // layer_tap
                MO(2),          // momentary layer
                LCTL(KC_C),     // Ctrl+C
                RGB_MOD ),      // per-key effect-next (fine on QMK)
};

QMK also emits keyboard.json (matrix pins, diode, MCU/USB identity); VIA/Vial add via/<kb>.json / vial.json.

Capability matrix

Each target supports a different feature set. The compiler consults this matrix to emit a warning and drop an unsupported binding to a no-op, rather than failing the build.

Lighting axes

AxisZMKQMKKeychron
underglow
backlight
per_key

ZMK has no per-key RGB matrix control.

Output routing

Output actionZMKQMKKeychron
usb
bluetooth* (incl. profile index)
toggle, none

Stock QMK is wired-only. ZMK and Keychron support Bluetooth output and profile indices.

Behaviors with a codegen path

BehaviorZMKQMKKeychron
Caps Word
Sticky key
Sticky layer
Tap dance
Macro
Combo

Which targets can I compile for?

  • No device connected (builder / demo) — all targets are available; you pick in the Identity panel.
  • A device connected — only that device's own firmware family is offered, so you cannot accidentally compile a ZMK keymap for a QMK board.

Readiness

Before a target will build cleanly it needs certain fields set (controller, USB ids, matrix wiring, Vial UID/unlock). The export modal runs a per-target readiness check and shows what is missing — see Export, build & flash → Readiness.

Roadmap

Behavior coverage continues to expand per firmware. The project README tracks the detailed, per-behavior status matrix (done / in-progress / planned).

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