Skip to main content

Specification

In order for VIA to configure a keyboard, it requires a definition of the keyboard - the physical layout of keys, any layout options, and other configurable elements like rotary encoders (knobs), lighting, etc.

These things are defined in a "keyboard definition"—a JSON file stored in the VIA Keyboards repository and served to VIA when that keyboard is connected.

To add official support, the keyboard implementation must first be present in QMK Firmware and its via keymap in VIA's external QMK userspace. The definition is then submitted to VIA Keyboards. See Configuring QMK for the complete repository workflow.

Here is a great video by Joe Scotto giving an overview of the process:

Keyboard Definition

Keyboard definitions are in JSON format. Valid properties are described below.

Name

  "name": "Macropad",

The name property denotes the name of the keyboard being defined.

V3 definitions may alternatively select a name dynamically from a value returned by the keyboard:

"name": {
"options": [
"Macropad",
"Macropad Pro",
"Macropad Special Edition"
],
"content": ["id_board_variant", 0, 3]
}

The keyboard returns a zero-based index into options through the custom-value command identified by content. VIA uses the selected name in the keyboard badge, device list, layout exports, Design tab, and diagnostics. If the command is unsupported, malformed, or outside the available range, VIA uses the first option.

Dynamic names allow hardware variants that share a VID, PID, matrix, and definition to identify themselves without duplicating the definition. A static string remains the correct choice when the displayed name never changes.

The dynamic name uses the same custom-value mechanism as a custom menu. In the example, channel 0 and value ID 3 are defined by the keyboard author; 3 is not a reserved dynamic-name ID. Any suitable value ID can be used as long as the definition and firmware agree.

See Dynamic keyboard name for a paired definition and QMK custom-value handler.

Vendor & Product ID

  "vendorId": "0x5241",
"productId": "0x1234",

The productId property corresponds to the USB product ID. Together with vendorId, it is used by VIA to identify the keyboard when it is plugged in.

Matrix

  "matrix": {"rows": 1, "cols": 6},

The matrix property defines how many rows and columns the PCB's switch matrix uses. These values must match the matrix dimensions generated by QMK, normally from the keyboard's data-driven matrix_pins and layouts properties in info.json.

Layouts

  "layouts": {
...
"keymap": [
[{"c": "#505557", "t": "#d9d7d7", "a": 7}, "0,0", "0,1", "0,2"],
["0,3", "0,4", "0,5"]
]
...
}

The keymap property corresponds to the KLE JSON exported by Keyboard Layout Editor. Each key has its switch row and column in the top-left legends and, optionally, its layout group and option in the bottom-right legends. Up to three key colors can identify alpha, modifier, and accent keys, to which VIA automatically applies its theme.

  "layouts": {
...
"labels": [
"Split Backspace",
"ISO Enter",
"Split Left Shift",
"Split Right Shift",
["Bottom Row", "ANSI", "7U", "HHKB", "WKL"]
],
...
}

The labels property is an optional array of string or string[] and defines the labels for the layout controls.

The order of the labels is important as the implicit index is used to map to the group number e.g. Split Backspace corresponds to layout option #0, ISO corresponds to layout option #1, etc.

If an item in the labels array is a string, it is presented as a toggle button, the off state maps to layout option choice #0 (the default), the on state maps to layout option choice #1.

If an item in the labels array is a string[], it maps to a select control with the first item in the array being used as the label for the control and the following items being used as labels of layout option choices #0, #1, #2, etc. In the example above, the Bottom Row is the label, ANSI maps to layout option choice #0, 7U maps to layout option choice #1, etc.

Documentation explaining how layout options work is here.

The menus element adds menus to VIA. It can contain one or more of the following built-in UI definitions:

  • "qmk_backlight"
  • "qmk_rgblight"
  • "qmk_backlight_rgblight"
  • "qmk_rgb_matrix"
  • "qmk_audio"

and/or a definition of custom UI, i.e. explicitly defining all the UI controls required.

For example, a definition enabling the built-in UI for QMK RGB Matrix could be done like so:

"menus": ["qmk_rgb_matrix" ]

or alternatively defined explicitly using custom UI definitions, like so:

...
"menus": [
{
"label": "Lighting",
"content": [
{
"label": "Backlight",
"content": [
{
"label": "Brightness",
"type": "range",
"options": [0, 255],
"content": ["id_qmk_rgb_matrix_brightness", 3, 1]
},
...
]
}
]
}
]

The complete documentation for custom UI is here.

If the firmware is using the stock implementation of a feature, i.e. it is enabled in the info.json or the rules.mk and not customized, then using one of the built-in UI definitions is all that is needed.

The built-in UI definitions are defined the same way as custom UI definitions (i.e. JSON format) and for reference are located here: https://github.com/the-via/keyboards/tree/master/common-menus. They can be used as examples to create custom UI definitions.

Keycodes

The optional keycodes property exposes additional groups of keycodes in VIA. For QMK lighting, new V3 definitions should select the module that matches the firmware subsystem:

  "keycodes": ["qmk_rgblight_keycodes"],
"menus": ["qmk_rgblight"],

Available QMK lighting keycode modules are:

ModuleKeycodes exposed
qmk_backlight_keycodesMonochrome Backlight (BL_*)
qmk_rgblight_keycodesRGBLight (UG_* on protocol 13)
qmk_rgb_matrix_keycodesRGB Matrix (RM_* on protocol 13)
qmk_backlight_rgblight_keycodesBacklight and RGBLight
qmk_lightingCompatibility fallback for older definitions

On VIA protocol 12 and earlier, QMK lighting uses the legacy unified RGB_* keycodes. On protocol 13, RGBLight and RGB Matrix use their separate UG_* and RM_* ranges. VIA selects the correct dictionary for each connected device.

Do not combine qmk_lighting with an explicit QMK lighting keycode module. When qmk_lighting is retained for compatibility, VIA attempts to infer the subsystem from standardized built-in lighting menus. Definitions with custom lighting menus should use an explicit module to avoid exposing both RGBLight and RGB Matrix keycodes.

The selected keycode module should match the corresponding built-in menu. The Design tab warns when, for example, an RGB Matrix menu is paired only with the RGBLight keycode module.

The lighting keycode case tables cover every Backlight, RGBLight, and RGB Matrix combination, as well as the protocol-dependent behavior of the legacy qmk_lighting fallback.

Custom Keycodes

customKeycodes assigns friendly labels to the keyboard-specific QMK keycode range. Array position 0 describes CUSTOM(0) (the first QK_KB keycode), position 1 describes CUSTOM(1), and so on.

"customKeycodes": [
{
"name": "Mode",
"title": "Cycle keyboard mode",
"shortName": "Mode"
},
{
"name": "Calibrate",
"title": "Start switch calibration"
}
]
  • name is the text shown in the keycode picker.
  • title is the longer description shown when the keycode is inspected.
  • shortName is an optional compact legend used when space is limited.

The firmware must implement the corresponding QK_KB_* keycodes in the same order. Adding a definition entry only exposes and labels the keycode; it does not implement its behavior.

Firmware Version

The optional top-level property is accepted for V3 definitions and defaults to 0:

"firmwareVersion": 0

Historically, this value described the expected VIA_FIRMWARE_VERSION. Current definitions should use the firmware-reported value directly in showIf expressions when controls differ between firmware releases:

"showIf": "{id_firmware_version} >= 5"

This allows one VID/PID and one definition to remain compatible with multiple firmware revisions. See Firmware-version conditions.