Custom QMK firmware?

Hey all, batch 16-er here (:headstone:) but I was wondering if anyone had successfully reflashed their 16’s keyboard with a custom QMK build yet? I usually enable some of the “weird” QMK features like space cadet, auto shift, etc. which can’t be configured through VIA. Hopefully one of the batch 1-3ers on the forum have similarly weird keyboard expectations :slightly_smiling_face:

Yessir! It’s not to hard to build a new firmware package, you just need the right Github repo and branch:

I’ve had success in porting my visualizer tonight!


v0.2.8-prep is an old development branch. You’ll want to pull the latest release branch.
Currently, it’s v0.2.9.

For anyone reading this later, don’t just grab v0.2.9, always check to see if there is a newer version release branch.


Awesome! Just what I was hoping to see :smiley:. Just wanted to make sure there weren’t any weird quirks for one reason or another.

Now I’ll just go back to waiting anxiously lol.

That’s pretty neat is that on Github?

1 Like

I have a several questions and requests.

First question - would anyone be willing to create a step by step idiot’s guide to customizing the keyboard? I have been able to connect to it with the web app and to adjust the rgb animation from there, but what I would like to do is to create and load some additional custom animations - this is on the clear ansi rgb keyboard.

Second question - can the customization be done through the via front end? If so, see first question.

Third question - does a tool exist that allows one to test things, in my case animations for starters, before loading them onto the keyboard?

Thanks in advance. I have been going in circles on this all day. I’m hoping that someone has figured this out and can provide some guidance, as I’m obviously not figuring things out by looking at the repos and the guides online.

1 Like

Do you mean, you want to create an entirely new custom animation?

Yes, I want to create a “band val pendulum” animation - a band that goes back and forth across the keyboard. I found the source for band_sat, band_val, and hue_pendulum, and have mocked something up.

In my happy place I could test this on some sort of web app or standalone app. I have no idea if such a thing exists.

For now, I’m trying to figure out if there is a way to load a config into via and test it or upload it to the keyboard from there. Presumably yes, but heck if I can figure it out. I will try to dig back into the documentation. I was able use the examples for the led matrix modules to put something together that pulls the current outside temperature and displays it in the led matrix modules. I have not yet dug into if I can update the led matrix modules separately. I have some rudimentary competence at tweaking things, but it helps me greatly to have an initial guide to follow.

Just to check, you want to do this on the keyboard, right? Not the led matrix modules. It’s different for each.

Yes, sorry, I should have been clear. I mentioned the LED matrix modules probably to make myself feel better that I could get something working.

Here, I am looking to customize the keyboard. Thanks for your engagement!

It sounds like yes, you want to create an entirely new custom animation.
In that case.

Second question: No, it can not be done through the Via front end / I’m afraid you would need to write code for your animation. Most QMK code is written in C.

Third question: I’m not certain, but really don’t think there is a tool available for testing qmk firmware outside of a real keyboard.

For step-by-steps, I do have a couple I’ve been kicking around. Getting the right files to build / compile firmware for the keyboard. And basic flashing firmware. But mostly aimed at flashing precompiled firmware, since once you’re compiling your own, you probably don’t need help there.

I’m comfortable writing the code, believe it or not. I wasn’t sure if, once I write said code, I could load it using via. I’m pretty clearly over my head here in terms of what it takes to do this from start to finish. I was hoping for a simulator of sorts to work out any kinks with the code prior to loading it onto the actual keyboard.

I was about to say that if I ever get this figured out, I would be happy to write something up. If you are willing to share your step-by-step, I would be happy to try it out, and note where I run into issues.

For normal use, you can configure your keyboard by going to Flashing or building firmware is not necessary, and it does carry risk. If you kill your keyboard, I presume it’s not covered by warranty.

• Keyboard QMK firmware, getting the right files to build.

This is only for the Framework 16. The Framework 13 does not use QMK.
I’ve seen a couple people unsure where to get the right branch to compile the firmware.

It’s presumed that you already have your QMK build environment setup. If not, follow this Running qmk doctor should say that QMK is ready to go.

Download the Framework Firmware repo

  1. Check the version number of the latest release
  2. Click the “tags” button on that page to confirm that a branch corresponding to the latest release is there
  3. Clone that particular branch with git clone -b <branchname> <remote-repo-url>
    For example:
git clone -b v0.2.9

QMK compiles from its home directory. See it’s current home directory with

qmk config user.qmk_home

If the Framework firmware repo got downloaded to a different location, you can either move the folder, or just point QMK to it

To point QMK to it / change QMK’s home directory

qmk config user.qmk_home=/[Path-To-The-Downloaded-Firmware]/

• Flashing / reflashing the Framework 16 keyboard firmware.

Be sure you have an external keyboard. Your keyboard won’t work if the wrong file or a bad file is flashed.

To flash firmware, you need to restart your keyboard or numpad into bootloader mode. Here are 3 options:

  • On Framework Laptop 16 Keyboard: Hold down left ALT and right ALT while
    installing the module
  • On Framework Laptop 16 Numpad: Hold down keys for 2 and 6 while installing the
  • Bootmagic reset: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
  • Keycode in layout: Press the key mapped to QK_BOOT if it is available

The QK_BOOT key is named Reset in Via ( It’s found in the “Special” section. Just place it on any key, then press the key.

When your keyboard enters bootloader mode, it will appear to your computer as a flash drive.

To flash or reflash a .uf2 firmware file, open the drive just like you would a real flash drive. Then just drag-and-drop the appropriate .uf2 file over to it. For example, framework_ansi_default_v0.2.9.uf2 for the ANSI (American) layout keyboard. Your keyboard will restart automatically and run the new firmware.

Which layout do I want? ANSI, ISO or JIS

ANSI (American) layout. Note the shape of the enter key.

ISO layout. British is shown, but this layout is valid for many languages.

JIS (Japanese) layout.

Official Framework .uf2 firmware files are here

If you’re flashing firmware that you complied yourself, you would usually just do that by command line, rather than dragging-and-dropping the file.

• Compile and flashing commands.

First, cleanup any files from previous builds. It saves you from problems. I always do this by just adding it in front of flashing or compile commands with &&. For example: qmk clean && qmk flash -kb framework/macropad -km default

qmk clean

Compile, creating a .uf2 file in your current directory. For example: qmk compile -kb framework/macropad -km default

qmk compile -kb framework/[KEYBOARD] -km [KEYMAP]

Compile and flash straight over. If your keyboard isn’t already in bootloader mode, QMK will kindly wait for you to do that at the end of the compiling process. A .uf2 file will also still be created in your current directory.

qmk flash -kb framework/[KEYBOARD] -km [KEYMAP]

Also, here is a Per-key color step-by-step

How to get to point you can have per key RGB control for keyboard and macropad? - #2 by MJ1


I would be thankful if you could let me know how it seems, if it’s simple and understandable enough. Maybe if you see something that could be better. I was thinking of creating a thread if it’s good.

1 Like

I absolutely will follow up. Thank you so much for sharing this!


@MJ1 - thank you! I have been able to load a custom animation. It generally works, but it only looks somewhat right at high brightness (fn + space to get there), so I have something not quite right that I need to figure out. It also does not show up in the via gui, but I can get to it with fn + e or fn + d, presumably I need to adjust something with via, but that’s for another day as well.

I will reply tomorrow with notes on the steps, noting where I adjusted things. I could not have gotten this going without your help, and I cannot thank you enough. This community is fantastic, and it’s people like you who make it that way. Thank you, thank you, thank you.

Have a great evening!

For anyone curious:

  1. Follow MJ1’s guide

  2. I added this to keyboards/framework/config.h

  1. I added this the end of quantum/rgb_matrix/animations/
#include "colorband_val_pendulum_anim.h"
  1. I created quantum/rgb_matrix/animations/colorband_val_pendulum_anim.h with the following contents:

// Change valuedelta to adjust range of value change. 0-255.
// Looks better with a low value and slow speed for subtle change.
// Value Pendulum - color moves in a wave to the right before reversing direction
static HSV VALUE_PENDULUM_math(HSV hsv, uint8_t i, uint8_t time) {
    uint8_t valuedelta = 9;
    int16_t v            = hsv.v + scale8(abs8(sin8(time) + (g_led_config.point[i].x) - 239) * 2, valuedelta); // 255 is too much overlaps on the left, 192 too little
    if ((v < 0) || ( v > 255)) {
    	v = 0;
    hsv.v = scale8(v, hsv.v);
    return hsv;

bool VALUE_PENDULUM(effect_params_t* params) {
    return effect_runner_i(params, &VALUE_PENDULUM_math);


  1. Grin like an idiot at being able to tweak things like this.

On a totally separate note, here’s what I am using to put the temp and conditons on the led matrix spacers. Warning, it’s hacky and at the moment hard codes cloud because that has been the weather here today. My regex is awful so go easy there too. Suggestions always welcome.

./inputmodule-control_cli_linux led-matrix --brightness 15 --symbols `inxi -w --wu i | sed -En 's/.*temperature:\s{1,1}([0-9]{1})([0-9]{0,1})([0-9]{0,1})\s{1,1}[CcFf]{1,1}\s{1,1}conditions:\s{1,1}([A-Za-z]*)\s([A-Za-z]*)/\1 \2 \3 /p'` degF ' ' cloud


Some updates to my prior post. @MJ1, I still owe you feedback on your steps. I will get that to by the weekend if not before.

Update to my steps in the prior post. I finally rtfm a little more. Not completely, but a little more.

Undo the changes to config.h and

  1. Add the following lines to the keyboard file. For me that was keyboards/framework/ansi/
USER_NAME := mycooluser
  1. Create a folder under the users directory with a name relevant for you (the qmk directions give better guidance here, but let’s say it is called mycooluser, as noted in the prior step

  2. create users/mycooluser/, adding the customizations there. Here is my current version of the file. The "band_val_backforth works better than value_pendulum in my opinion



// Change valuedelta to adjust range of value change. 0-255.
// Looks better with a low value and slow speed for subtle change.
// Value Pendulum - color moves in a wave to the right before reversing direction
static HSV VALUE_PENDULUM_math(HSV hsv, uint8_t i, uint8_t time) {
    uint8_t valuedelta = 9; //12;
    int16_t v            = hsv.v + scale8(abs8(sin8(time) + (g_led_config.point[i].x) - 239) * 2, valuedelta);
    if ((v < 0) || ( v > 255)) {
    	v = 0;
    hsv.v = scale8(v, hsv.v);
    return hsv;

bool VALUE_PENDULUM(effect_params_t* params) {
    return effect_runner_i(params, &VALUE_PENDULUM_math);


static HSV BAND_VAL_BACKFORTH_math(HSV hsv, uint8_t i, uint8_t time) {
    int16_t v = hsv.v - abs(scale8(g_led_config.point[i].x, 228) + 28 - sin8(time)) * 8;
    hsv.v     = scale8(v < 0 ? 0 : v, hsv.v);
    return hsv;

bool BAND_VAL_BACKFORTH(effect_params_t* params) {
    return effect_runner_i(params, &BAND_VAL_BACKFORTH_math);


static HSV BAND_SAT_BACKFORTH_math(HSV hsv, uint8_t i, uint8_t time) {
    int16_t s = hsv.s - abs(scale8(g_led_config.point[i].x, 228) + 28 - sin8(time)) * 8;
    hsv.s     = scale8(s < 0 ? 0 : s, hsv.s);
    return hsv;

bool BAND_SAT_BACKFORTH(effect_params_t* params) {
    return effect_runner_i(params, &BAND_SAT_BACKFORTH_math);


Edit to add: this computer is this nerd’s dream machine. I hadn’t fiddled with qmk before, but with assistance from people like MJ1 (not @'ing you here to try not to spam you), I have been able to modify some existing animations to create ones customized for me. Thank you to everyone at Framework for creating this computer.


No worries, no rush.


Ok, very belatedly getting to this.

I am not very good with git, so I followed the basic qmk setup steps, then cloned the framework-specific one per your instructions. I then ran

qmk config user.qmk_home=/home/mycooluser/restofthepath/qmk_firmware

to point qmk to the framework repo that I set up following your steps. I then deleted the repo that had been set up as part of the qmk newbs getting started process.

To load the firmware onto the keyboard, I set one of the keys as the reset key, then drag and dropped the file onto the “usb” drive that the keyboard shows up as when reset. After loading the firmware I go back and turn off the reset function for the key.

I managed to forget to do that one time after I had loaded firmware, and dragging it again to the “usb” keyboard drive didn’t work, presumably since it was not an updated version. Removing and reinstalling the touchpad module and keyboard did reset the keyboard and get things working again.

Thank you again for the help, as I don’t know that I would have succeeded without your guidance. I’ve got at least one more original animation in mind, but I have to sit down and design it then code it up. If I ever get really motivated and find the time, I would love to put together a simulator for the animations. To be honest, my doing so likely is a pipe dream, due to time and ability constraints.

Note for anyone who comes across this later - I initially mistyped the command above, then fixed it after I saw MJ1’s reply below, which has my original incorrect command quoted.

1 Like