Krux Installer is a GUI based tool to flash Krux without typing any command in terminal for flash the firmware onto the device.
Since v0.0.22, Krux Installer runs fully offline. The Krux firmware binaries are bundled inside the installer at build time, so it no longer contacts GitHub at runtime — no internet connection is required to flash your device.
Earlier versions fetched the firmware over the network: the installer queried GitHub for the available releases, let you pick a version, then downloaded, verified and unzipped the assets before flashing. All of that runtime networking has been removed. The installer no longer:
- checks your internet connection on startup;
- queries GitHub for the list of available firmware versions;
- downloads, verifies or unzips firmware assets on your machine.
Instead, each release ships with a single firmware version already embedded, verified and unpacked inside the binary. The user flow is now simply: open the installer → select your device → flash.
Each release ships with a fixed firmware version embedded in the binary
(the current one is v26.03.0). To flash a different firmware version,
download the installer release that bundles it, or build from source with
your desired version (see Firmware embedding (for developers)).
Available for:
- Linux:
- Debian-like;
- Fedora-like;
- In the experimental phase, we have a nix flake for development.
- Windows;
- MacOS:
- intel processors;
- arm64 processors (M1/M2/M3/M4).
Make sure you have python:
python --versionGenerally, all Linux come with python.
Follow the instructions at python.org
Before installing krux-installer source code, you will need prepare the system:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"brew install pythonand add this line to your ~/.zshrc:
alias python=python3Python's ssl module relies on OpenSSL for cryptographic operations.
Ensure that OpenSSL is installed on your system and is compatible with the
Python version you're using.
Since we expect that you're using the Python installed with Homebrew, it's recommended to install OpenSSL through Homebrew if it's not already installed:
brew install opensslAfter installing OpenSSL, make sure it's linked correctly:
brew link --force opensslThis ensures that the OpenSSL libraries are available in the expected locations that Python can find and use.
Library paths on MacOS involves verifying that the environment variables and system
configurationsare correctyly set to find the necessary libraries, such as OpenSSL,
which is crucial for the ssl module in Python.
On MacOS, the dynamic linker tool dyld uses environment variabes to locate shared
libraries. The primary environment variable for specifying library paths is
DYLD_LIBRARY_PATH.
Adding the lines below to your ~/.zshrc (or similar) the DYLD_LIBRARY_PATH
will be set each time you open a new terminal session (and therefore the OpenSSL
libraries libcrypto.dylib and libssl.dylib will can be found):
OPENSSL_MAJOR_VERSION=`openssl --version | awk '{ print $2}' | cut -d . -f1`
OPENSSL_FULL_VERSION=`openssl --version | awk ' { print $2}'`
export DYLD_LIBRARY_PATH="/opt/homebrew/Cellar/openssl@$OPENSSL_MAJOR_VERSION/$OPENSSL_FULL_VERSION/lib:$DYLD_LIBRARY_PATH"Follow the steps to install UV on [https://docs.astral.sh/uv/reference/storage/]
Clone the repository:
git clone --recurse-submodules https://github.com/selfcustody/krux-installer.gitInstall python dependencies:
uv syncIf already cloned the repo without using --recurse-submodules,
use the command below to clone the needed submodules:
git submodule update --initKrux-Installer uses poe task manager for formatting, linting, tests,
coverage and build.
uv run poeuv run poe formatuv run poe lintuv run poe testFor systems without a window manager:
# Linux only
uv run poe test --no-xvfbYou can see all coverage results opening you browser and type
file:///<folder>/krux-installer/htmlcov/index.html (assuming
folder is where you placed the krux-installer project).
uv sync --extra builder
uv run poe fetch-firmware
uv run poe build-linuxuv sync --extra builder
uv run poe fetch-firmware
uv run poe build-macosuv sync --extra builder
uv run poe fetch-firmware
uv run poe build-winIt will export all project in a
one-file binary:
- linux:
./dist/krux-installer - macOS:
./dist/krux-installer.app/Contents/MacOS/krux-installer - windows:
./dist/krux-installer.exe
To more options see .ci/create-spec.py against the PyInstaller options.
The installer ships with firmware binaries embedded at build time. This section documents how the embedding pipeline works and how to use locally built binaries for development or testing.
prebuild/
└── fetch_firmware.sh # canonical script: download → verify → embed
.firmware_download/ # landing folder (gitignored)
├── krux-<version>.zip
├── krux-<version>.zip.sha256.txt
├── krux-<version>.zip.sig
└── selfcustody.pem
src/utils/firmware/ # packing folder (committed, embedded in the binary)
└── <version>/
├── amigo.kfpkg
├── bit.kfpkg # not present in all releases
├── cube.kfpkg
├── dock.kfpkg
├── embed_fire.kfpkg
├── m5stickv.kfpkg
├── tzt.kfpkg
├── wonder_k.kfpkg
├── wonder_mv.kfpkg
└── yahboom.kfpkg
The .firmware_download/ landing folder holds the raw assets from GitHub
(zip, checksum, signature and public key). It is gitignored and can be
deleted after a successful build.
The src/utils/firmware/<version>/ packing folder contains only the
extracted .kfpkg files — one per supported device. These are committed
to the repository and embedded into the installer binary by PyInstaller
at build time.
uv sync --extra builder
uv run poe fetch-firmwareThis runs prebuild/fetch_firmware.sh, which:
- Downloads the release zip, SHA256 checksum, ECDSA signature and
selfcustody.pemfrom GitHub into.firmware_download/; - Verifies the SHA256 checksum (
sha256sumon Linux,shasumon macOS); - Verifies the ECDSA signature with
openssl(warns and continues ifopensslis not available); - Extracts
kboot.kfpkgfor each supported device and saves it assrc/utils/firmware/<version>/<device>.kfpkg.
Required tools in PATH: curl, unzip.
Optional (for full verification): sha256sum/shasum, openssl.
If you are developing Krux firmware and want to test your locally compiled
binaries with the installer, place your .kfpkg files directly into the
packing folder — no download step needed:
src/utils/firmware/<version>/
├── amigo.kfpkg ← your locally built binary
└── ...
The version directory must match the FIRMWARE_VERSION constant in
src/utils/constants/__init__.py. When running the installer from source
(uv run poe dev), it will pick up whatever .kfpkg files are present
in that folder.
Note: locally built binaries are unsigned. The installer will still flash them correctly; only the pre-build verification step (
fetch_firmware.sh) requires a valid signature. No signature is checked at flash time.
After building the installer, the landing folder is no longer needed:
rm -rf .firmware_download/The packing folder (src/utils/firmware/) should be kept as-is if you
want to commit the firmware files for reproducible builds.
