Getting Started with QMK on the ZSA Voyager

I'd never touched QMK before getting my ZSA Voyager. Although Oryx makes programming your layout dead simple, its current limitations and missing QMK tweaks eventually drew me into the QMK rabbit hole, even though I’d prefer sticking with it for simplicity and long‑term maintenance.

There is also a tool for using Oryx while adding custom QMK tweaks, so you could make changes in both Oryx and QMK interchangeably. However, I didn't find it worked well enough with my setup due to merge conflicts.

Building and Flashing Your Voyager Layout from Source

Here's a summary of how you can flash your Voyager layout from source code on macOS.

  1. Clone the QMK firmware repository:

    git clone https://github.com/zsa/qmk_firmware.git

    Or fork it as your own qmk_keymap repository.

  2. Navigate to the cloned folder: cd qmk_firmware.

  3. Install QMK: brew install qmk/qmk/qmk.

  4. Set up QMK: qmk setup.

  5. Confirm installation of dependencies, and cloning submodules.

  6. Download the source code for your layout from Oryx:

Where to download source code oryx
  1. Copy the contents of the *_source folder (from the Oryx .zip) into qmk_firmware/keyboards/voyager/default (or your preferred folder).
  2. Compile the layout: make voyager:default.
  3. Flash the compiled layout: make voyager:default:flash.

Using the QMK Configurator

To try the official QMK Configurator, generate a JSON for import—it’s useful for learning QMK keycodes, though in practice it usually will not surpass Oryx for Voyager users.

  1. Generate a JSON file:

    qmk c2json -km voyager:default -kb voyager keyboards/voyager/keymaps/custom/keymap.c --no-cpp > keymap.json

  2. In the JSON file, change the keyboard to zsa/voyager.

  3. Navigate to QMK Configurator and upload a keymap.json.

QMK Configurator Voyager

Handpicked QMK Keycodes and Tricks

I experimented with a few tweaks to improve my workflow but ended up not using most of them. I kept the Repeat Key, custom macros, and smaller features like snake_case and numword toggles.

Good sources for QMK tweaks:

Repeat Key

I originally tried to use it to repeat letters when typing regular words such as “dazzle”. While it's not bad, I didn't end up using it—and once I stopped practicing typing regularly, I didn't miss it.

I recommend placing it in an easy-to-reach position. I placed it in my former Tab key position, so it acts as Tab when needed—or for indentation, I press Tab once and repeat it.

For me, its main strength is repeating simultaneous keypresses like Cmd+W.

Repeat Key QMK Docs

Leader Key

Oryx likely will not add Leader Key anytime soon due to the UI complexity it would introduce.

I couldn't find a spot for it in my workflow—Vim's leader key might be enough.

Leader Key QMK Docs

X-Case

I'm using a simple snake*case toggle, which suffices. The X-Case idea is cool—you press *+ X-Case button to get snake_case or-+X-Case for dash-case (or others)—but I don't have enough uses for it and the QMK config overhead isn't worth it.

X-Case

Caps word and num word

You can extend this with word toggles (for X‑Case or num layers) that automatically end on spaces or other word‑breaking characters. I like it for snake_case and num_word.

Better Macros

Full macro control in QMK is great. I use it for Czech diacritics (without switching input sources) and hardware snippets like my email or phone number. Alternatives exist (IDE snippets, OS text replacements, Karabiner), but hardware macros work everywhere.

case ST_MACRO_22:
  if (record->event.pressed) {
      if (get_mods() & (MOD_BIT(KC_LSFT) | MOD_BIT(KC_RSFT)) || host_keyboard_led_state().caps_lock || is_caps_word_on()) {
          send_unicode_string("É");
      } else {
          send_unicode_string("é");
      }
  }
  break;
case ST_MACRO_16:
  if (record->event.pressed) {
      SEND_STRING("filip@filiphalas.com");
  }
  break;