---
title: Installing ZMK
sidebar_label: Installing ZMK
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

export const OsTabs = (props) => (
    <Tabs
    groupId="operating-system"
    queryString
    defaultValue="linux"
    values={[
      { label: "Linux", value: "linux" },
      { label: "Windows", value: "win" },
      { label: "Mac OS", value: "mac" }
    ]}
  >
    {/* eslint-disable-next-line */}
    {props.children}
  </Tabs>

);

Unlike other keyboard firmwares, ZMK Firmware has been built from the ground up to allow users to manage
their own keyboard configurations, including keymaps, specific hardware details, etc. all outside of the
core ZMK Firmware source repository.

In addition to this, most users will not need to install any complicated toolchains or tools to build ZMK. GitHub Actions is used instead to automatically build the user's configured firmware for them.

:::info[Something Isn't Working?]

If you run into any issues when following these instructions, please [file an issue on GitHub](https://github.com/zmkfirmware/zmk-cli/issues) or [join us on Discord](https://zmk.dev/community/discord/invite) and let us know what went wrong so we can improve ZMK CLI and this guide.

:::

## Summary

The following steps can be taken to obtain an installable firmware image for your device, without the need
to install any compiler or specialized toolchain. This is possible by leveraging [GitHub Actions](https://github.com/features/actions)
to build your firmware for you in the cloud, which you can then download and flash to your device.

Following the steps in this guide, you will:

1. Install ZMK CLI, a command line tool for setting up ZMK.
1. Create a new repository in GitHub that will contain your user config.
1. Use ZMK CLI to clone the repo to your computer so you can edit the files.
1. Select a keyboard to use and update the `build.yaml` file so GitHub will build firmware for that keyboard.
1. Add your own `.keymap` and `.conf` files to customize your keymap and enable/disable other ZMK features.
1. Commit and push the updates to trigger a new GitHub Action run to build the firmware.

## Prerequisites

You will need to install a few tools before you can get started.

Many instructions in this guide use commands that need to be run in a terminal application.

- On Windows, use [Windows Terminal](https://apps.microsoft.com/detail/9n0dx20hk701) or PowerShell.
- On other operating systems, the terminal program is usually just named "Terminal".

### Install Git

Open a terminal and run the following command. If Git is already installed, it will print out a version number.

```sh
git --version
```

If it gives an error instead, install Git from https://git-scm.com/install/. Close and re-open your terminal and run the `git --version` command again to check if it installed correctly.

:::note
This guide will have you run several more `git` commands later. If you aren't familiar with Git, check out [Learn The Basics Of Git In Under 10 Minutes](https://www.freecodecamp.org/news/learn-the-basics-of-git-in-under-10-minutes-da548267cc91/) to help you get started.
:::

### Set Up a GitHub Account

You will need a GitHub account. [Create an account](https://github.com/signup) if you don't have one yet.

Next, you will need to authenticate your local Git installation with GitHub. There are several ways to do this, but the following two are the simplest. Pick whichever seems easiest to you:

#### Authenticate with GitHub CLI

Install [GitHub CLI](https://cli.github.com/) and run the following command in a terminal. Follow the instructions it gives you, and it will open GitHub in a web browser for you to log in.

```sh
gh auth login
```

#### Authenticate with a Personal Access Token

Create a [personal access token](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token) and make sure to create it with the "workflow" scope option selected.

When running `git` commands later in this guide, Git will ask for your username and password. Enter your GitHub username, but **do not enter your password**. Instead, paste your access token for the password. You won't be able to see the token again after you create it, so keep the page open until you've done this and/or copy it to a secure location. If you lose the token, simply create another one.

### Install Python and pipx

ZMK CLI requires Python version 3.10 or above.

There are several ways you can install ZMK CLI, but for simplicity, this guide will use [pipx](https://pipx.pypa.io/stable/). (If you are already familiar with another Python package manager such as [uv](https://github.com/astral-sh/uv), you can install the `zmk` package with it instead, but that will not be covered in this guide.)

The instructions for installing Python and pipx differ depending on your operating system.

<OsTabs>
<TabItem value="linux">

Python comes preinstalled on most Linux distributions, but pipx needs to be installed separately. In case Python isn't already installed, this guide will have you install both. Pick the commands relevant to the distribution you are using:

#### Ubuntu 23.04 or above

```sh
sudo apt update
sudo apt install python3 pipx
pipx ensurepath
```

#### Ubuntu 22.04

```sh
sudo apt update
sudo apt install python3
python3 -m pip install --user pipx
python3 -m pipx ensurepath
```

#### Ubuntu 20.04

Ubuntu 20.04 comes with an older version of Python. You can install Python 3.10 from the deadsnakes PPA with the following commands:

```sh
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt install python3.10
python3.10 -m pip install --user pipx
python3.10 -m pipx ensurepath
```

You will then need to replace `python3` with `python3.10` in the rest of the installation instructions.

#### Fedora 35 or above

```sh
sudo dnf install python3 pipx
pipx ensurepath
```

If you have an older version of Fedora, you will need to update your operating system to a newer version or [build Python from source](https://docs.python.org/3/using/unix.html#building-python).

#### Other distributions

Install Python 3 and pipx using your distribution's package manager. If there is no package for pipx, install it with `pip` after installing Python:

```sh
python3 -m pip install --user pipx
python3 -m pipx ensurepath
```

Check the version of Python you installed:

```sh
python3 --version
```

If this prints a version less than 3.10, you will need to update your operating system to a newer version or [build Python from source](https://docs.python.org/3/using/unix.html#building-python).

</TabItem>

<TabItem value="win">

Open https://www.python.org/downloads/ and select "Download Python install manager". Run the installer, then open a terminal and run the following command to install the latest version of Python 3:

```sh
py install 3
```

Next, install pipx:

```sh
py -m pip install --user pipx
py -m pipx ensurepath
```

</TabItem>

<TabItem value="mac">

First, install Homebrew from https://brew.sh/. Next, open a terminal and run:

```sh
brew install pipx
pipx ensurepath
```

This should automatically install Python 3 if it is missing.

</TabItem>
</OsTabs>

### Verify pipx Install

Close and re-open your terminal, then run:

```sh
pipx --version
```

It should print a version number. If not, go back to the previous step and make sure you installed pipx correctly. You can also try logging out of your computer and logging back in to make sure any environment variables changes made during installation take effect.

### Install ZMK CLI

Finally, we'll install ZMK CLI. Open a terminal and run:

```sh
pipx install zmk
zmk --version
```

It should print a version number if everything installed correctly.

On Linux, you may get an error saying you need to install another package such as `python3.10-venv`. If so, follow the instructions in the error message, then try the above commands again.

## Config Repo Setup

Now that ZMK CLI is installed, you can use it to initialize a repository.

The `zmk init` command walks you through creating a GitHub repository, then clones it to your computer so you can edit it.

<details>
  <summary>I already cloned my repo</summary>

If you have already created a repo and cloned it to your computer, for example with the old ZMK setup script, you do not need to do this. Instead, run the following command to point ZMK CLI to your repo, replacing `/path/to/zmk-config` with the actual path to the repo folder.

```sh
zmk config user.home "/path/to/zmk-config"
```

Then, [skip to the next step](#add-a-keyboard).

</details>

Open a terminal and use the `cd` command to move to a folder where you'd like to place the ZMK files (it will create a `zmk-config` subfolder in this location), then run `zmk init`. For example:

```sh
cd ~/Documents
zmk init
```

Follow the instructions it gives you. If you already have a ZMK config repo on GitHub, you can enter its URL when prompted, for example:

```
Repository URL: https://github.com/myusername/zmk-config
```

Otherwise, leave this first prompt blank and press <kbd>Enter</kbd>, and it will walk you through creating a new repo.

Once you finish following all the instructions, you will have a copy of the repo stored on your computer. All `zmk` commands will run on this repo (unless the working directory is inside a different repo). If you ever forget where the repo is located, you can run `zmk cd` to find it.

### Add a Keyboard

To start building firmware for a new keyboard, run the following command:

```sh
zmk keyboard add
```

Follow the instructions to select a keyboard (and controller board if necessary). It will add the keyboard to your repo's `build.yaml` file so GitHub knows to build it, and it will create `config/<keyboard>.keymap` and `config/<keyboard>.conf` files for you to edit.

<details>
  <summary>My keyboard isn't listed</summary>

If ZMK doesn't support your keyboard by default, you have two options:

**Add a Module**

ZMK can be extended with [modules](features/modules.mdx) to add new keyboards. If someone has already created a module for your keyboard, run the following command to add it, replacing `<url>` with the URL of the Git repository for the module:

```sh
zmk module add <url>
```

For example, `zmk module add https://github.com/cannonkeys/zmk-cannonkeys-keyboards` would add support for CannonKeys keyboards.

Run `zmk keyboard add` again, and the new keyboards should appear in the list.

**Create It Yourself**

If nobody has created a module for your keyboard yet, or if it is your own custom design, you will need to set it up yourself. Your config repo is already set up as a module, so you can define new keyboards there. See ZMK's [new keyboard shield guide](development/hardware-integration/new-shield.mdx) for more information.

ZMK CLI can also help generate some of the boilerplate for defining a new keyboard:

```sh
zmk keyboard new
```

</details>

### Edit Your Keymap and Configuration

See the [customizing ZMK](customization.md) documentation for instructions on editing your keymap and configuring ZMK settings.

As a shortcut to open your keymap in a text editor, you can run the following command, replacing `<keyboard>` with the ID of the keyboard you chose earlier:

```sh
zmk code <keyboard>
```

If you have an editor like [VS Code](https://code.visualstudio.com/) that can open a folder, you can also run the command without a keyboard ID to open your config repo directly:

```sh
zmk code
```

The first time you run this command, it will try to identify which text editors you have installed and ask you which one to use. If you want to change this later, change the [`core.editor`](zmk-cli.mdx#coreeditor) setting.

### Commit and Push to GitHub

After you've changed your keymap to your liking, you need to commit and push your changes.

Run the following commands to go to the repo directory, mark all your changed files to be added to the commit, create the commit, and push it to GitHub.

```sh
zmk cd
git add .
git commit -m "Initial commit"
git push
```

The text after `-m` is the "commit message", which gives a name to the commit. This is your first commit, so we're calling it "initial commit" here, but you can name it whatever you like. When you make more commits later, it's a good idea to use the commit message to write a description of the changes you made.

:::warning

If the `git push` command asks you for a username and password, enter your GitHub username, but **do not enter your password**. Instead, paste your access token for the password. (Go back to the [GitHub account setup instructions](#set-up-a-github-account) if you need to create a token.)

:::

## Install the Firmware

### Download the Archive

Once you push a commit, GitHub will automatically run the action to build your keyboard firmware files. Run the following command to open the GitHub Actions page in your browser:

```sh
zmk download
```

Or, you can manually open your GitHub repository in your browser and click the "Actions" tab at the top.

![](./assets/user-setup/github-actions-link.png)

Once you have loaded the Actions tab, select the top build from the list. Once you load it, the right side panel will include
a link to download the `firmware` upload:

![](./assets/user-setup/firmware-archive.png)

Once downloaded, extract the zip and you can verify it should contain one or more `.uf2` or `.hex` files, which contain the firmware you need to write to your keyboard.

### Flash UF2 Files

If your firmware contains a `.uf2` file, then you flash the new firmware by putting the keyboard into bootloader mode and copying the file directly to it in file explorer.

First, put your keyboard into bootloader mode by double clicking the reset button (either on the MCU board itself, or the one that is part of your keyboard). The controller should appear in your OS as a new USB storage device.

Once this happens, copy the correct UF2 file (e.g. left or right if working on a split), and paste it onto the root of that USB mass
storage device. Once the flash is complete, the controller should unmount the USB storage, automatically restart and load your newly
flashed firmware. It is recommended that you test your keyboard works over USB first to rule out hardware issues, before trying to
connect to it wirelessly.

:::warning[Split keyboards]

For split keyboards, only the central half (typically the left side) will send keyboard outputs over USB or advertise to other devices
over bluetooth. Peripheral half will only send keystrokes to the central once they are paired and connected. For this reason it is
recommended to test the left half of a split keyboard first.
Please refer to [split keyboards documentation](features/split-keyboards.md) for more information.

:::

### Flash Hex Files

If your firmware contains a `.hex` file, then you will use DFU to flash the firmware. [QMK Toolbox](https://qmk.fm/toolbox) is an easy-to-use tool with support for DFU flashing.

Open QMK Toolbox, click the "Open" button, and select the correct `.hex` file (e.g. left or right if working on a split). Consult the documentation for your keyboard to figure out how to enter bootloader or DFU mode (often this is done by pressing a pair of buttons on the keyboard or by holding a specific key as you plug in the USB cable), and once QMK Toolbox detects the keyboard, click "Flash" to flash the firmware.

## Wirelessly Connecting Your Keyboard

ZMK will automatically advertise itself as connectable if it is not currently connected to a device. You should be able to see your keyboard from the bluetooth scanning view of your computer or phone / tablet. It is reported by some users that the connections with Android / iOS devices are generally smoother than with laptops, so if you have trouble connecting, you could try to connect from your phone or tablet first to eliminate any potential hardware issues with bluetooth receivers.

ZMK supports multiple BLE “profiles”, which allows you to connect to and switch among multiple devices. Please refer to the [Bluetooth behavior](keymaps/behaviors/bluetooth.md) section for detailed explanations on how to use them. If you don't make use of the mentioned behaviors you will have issues pairing your keyboard to other devices.

### Connecting Split Keyboard Halves

For split keyboards, after flashing each half individually you can connect them together by resetting them at the same time. Within a few seconds of resetting, both halves should automatically connect to each other.
Please refer to [the pairing section in the split keyboards documentation](features/split-keyboards.md#pairing-for-wireless-split-keyboards) for more information.

:::note

If you have issues connecting the halves, make sure that both sides are getting powered properly through USB or batteries, then follow the
[recommended troubleshooting procedure](troubleshooting/connection-issues.mdx#split-keyboard-parts-unable-to-pair). This is typically necessary if you
swapped firmware sides between controllers, like flashing left side firmware to the same controller after flashing the right, or vice versa.

:::
