UHK Agent: the configurator for the Ultimate Hacking Keyboard
Ultimate Hacking Keyboard configurator
At a glance
- What is it?
- Agent is the Electron and TypeScript configuration application for the Ultimate Hacking Keyboard, an open firmware keyboard that exposes its keymap, layers and macros over USB. The project ships a desktop build, a web build for demonstration, and a monorepo with the firmware-facing tools that read and write the device's own configuration formats.
- Who is it for?
- Agent suits an owner of the Ultimate Hacking Keyboard who wants to edit the keymap, the layers and the macros in a graphical interface rather than in text files, and who wants to see the firmware-level effect of a change. It is the wrong tool for a keyboard without the hardware, since the README says the application will not get past the opening screen, and the wrong choice for a different vendor's board.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Agent is and who it is for
Agent is the configuration application of the Ultimate Hacking Keyboard, and the README makes its audience clear in the first paragraph. It asks people not to build Agent from source unless they want to develop it, because using an existing release is far easier for everyone involved.
That instruction is unusual in a repository README and it tells you the shape of the project. This is an application that runs against real hardware, and the normal path for a user is a download.
There are two ways to get it. If you own a UHK, you download the latest desktop build from the releases page, and on Linux you take the AppImage, make it executable and run it with the --no-sandbox option, with a note that on recent Ubuntu versions you may need the libfuse2t64 package. If you do not own a UHK, you can try the web build in your browser, and the README is explicit that this is meant for demonstration purposes. The same limitation applies to the desktop build: without the hardware you will not get past the opening screen.
The homepage is the project's GitHub Pages site, the primary language is TypeScript, and the recent releases are v11.0.0 from 2026-10-06, v10.1.0 from 2026-06-23 and v10.0.0 from 2026-05-03, so the application is on a conventional semantic version line and is released regularly.
The licence field on the repository records a custom licence that GitHub cannot classify, with the terms in the LICENSE file, and the package.json says See in LICENSE, so the file is the place to read.
Building the desktop application from source
The build is a three command sequence once the toolchain is in place.
git clone [email protected]:UltimateHackingKeyboard/agent.git
cd agent
npm run install
npm run build
npm run electronThe first step is dependencies. The README asks for Node.js 20.x, installed with the operating system package manager, and notes that Mac users can install it with brew, and that a Node Version Manager is the way to hold several versions on one machine. There is a .nvmrc at the root of the repository for that purpose. libusb is also needed, with the per-platform commands given, apt-get install libusb-dev libudev-dev g++ on Debian-based systems and brew install libusb libusb-compat on macOS.
The npm run install script is worth understanding, because it is a workaround for something specific. The README explains that it wraps npm ci --ignore-scripts and then the postinstall script, which allows dependency install scripts to be skipped. Agent currently has no dependencies that require post-install steps, so this serves as a workaround until npm 12 ships with Node.js.
That last detail is a small time capsule. The reason for skipping install scripts is that npm was tightening what install scripts may do, and a project that vendors native modules through Electron and node-hid and serialport has to comply. A tool that talks to a keyboard over USB HID and over a serial port is exactly the kind of project that runs native code at install time.
The package.json confirms the shape of the dependency tree, with electron at 43.3.0, electron-builder for packaging, electron-updater for updates, node-hid and serialport for talking to the device, and a webpack and TypeScript toolchain with ts-loader and tsx. It also lists several versions that are worth noting, since the project pins the parts that matter for a hardware application: the firmware version at 18.0.3, the device protocol version at 4.19.0, the user config version at 15.0.0 and the hardware config version at 1.0.0.
The monorepo, the web build and the workspace rules
The repository is a monorepo, and the top level layout shows the parts. There is a packages/ directory holding the individual packages, with the web front end in packages/uhk-web/ named in the development section, plus build/, doc/, scripts/, rules/, cla/ and smart-macro-docs/ directories, and a lerna.json for the monorepo tooling with lerna-lite in the dependencies.
The web application has its own development loop.
npm run server:webThe app is then at http://localhost:8080, and the README notes that it reloads automatically when you make changes. That is a separate build target from the Electron application, and it exists because the same front end code has to run in a browser for the demonstration build and inside Electron for the desktop build. The asset path in the README's logo reference, packages/uhk-web/src/assets/images/agent-logo-with-text.png, confirms the layout.
There is a specific rule about how dependencies are installed, and it is the kind of rule that saves an afternoon of confusion. The npm workspace install works in hoisted mode, which the README says is not really suitable for this project. If you add or update a dependency of a package, you navigate to that package's directory, edit its package.json, and run npm install --ignore-scripts there rather than at the root.
The rest of the repository's tooling is conventional and modern. Linting is eslint with a flat config, styling is stylelint with the standard SCSS configuration, there is a .cursor/ directory, a .editorconfig, and a .metadata_never_index file that stops search engines indexing the local build output. The CHANGELOG.md and an NPM_UPDATES.md sit at the root, and there is a SECURITY.md and a CONTRIBUTING.md for the contribution path.
What the version numbers in the package mean
The most interesting thing in the package.json is not a dependency but the set of version fields that sit alongside the application version.
The application version is 11.0.0. The firmware version is 18.0.3. The device protocol version is 4.19.0. The user config version is 15.0.0 and the hardware config version is 1.0.0.
That is a deliberate versioning discipline, and it tells you more about the project than a feature list would. A configuration application for hardware has to be aware of three separate things that change at different rates. The application changes when the interface changes. The firmware changes when the keyboard's own software changes, and the application has to know which firmware behaviour to expect. The device protocol version covers the wire format the application speaks to the keyboard, which has to stay in step with the firmware. The user config and hardware config versions cover the formats of the files the application writes, which have to be readable by the keyboard's own tooling.
Because these versions are separate, an application release does not necessarily mean a firmware release, and a user reading the release notes can see which combination is expected. That is the difference between a project that treats hardware as an interface with a contract and one that treats it as a device it happens to talk to.
It also explains why the application checks the device at startup, and why the README says a user without the hardware will not get past the opening screen. The first thing the application does is identify what it is talking to and whether the versions line up.
Where UHK Agent is the wrong choice
The first limitation is the hardware dependency, and the README does not soften it. Without a UHK, the desktop application will not get past the opening screen, and the web build is for demonstration only. So this is not a general purpose keyboard configurator, and it cannot be used to try the interface before buying the board.
The second is that the toolchain constraints are narrow and the documentation is inconsistent about them. The README's build section says Node.js 20.x, while the package.json engines field requires Node 24.18.1 or newer and below 25, with npm 11.13.0 or newer and below 12, and there is a check-node-version package in the dev dependencies that will enforce the latter at install time. A contributor who follows the README literally will hit the version check rather than a build error, which is a reasonable design but an easy first stumbling block.
The third is the desktop distribution story. On Linux the AppImage needs the --no-sandbox option and on recent Ubuntu the libfuse2t64 package, which are the two classic symptoms of an Electron application that has to talk to USB hardware, and a user on a distribution without the fuse package has to work around it.
The fourth is the build weight. The project is a monorepo with a webpack build, an Electron build and a web build, and the repository carries a rules/ directory and a cla/ directory, which suggests the conventions for working in it are themselves a substantial part of the onboarding.
The fifth is that the documentation for users is deliberately thin, because the expectation is that you use a release. A user who wants to understand what the tool does to their keyboard is expected to read the documentation site rather than the repository.
How UHK Agent compares with the QMK configurator and with editing the firmware directly
The comparison with the QMK configurator is the closest one, because QMK is the dominant open firmware for custom keyboards and its browser based configurator has set the expectation for what this kind of tool looks like. The difference in approach is that the QMK configurator is generic and covers the whole QMK feature set, keymap layers, macros, combos and the rest, whereas Agent is specific to one keyboard and can therefore expose exactly what that keyboard supports.
The trade is depth against breadth. QMK can configure a board you have not seen before, and it has to be generic enough to handle the whole ecosystem. Agent knows the Ultimate Hacking Keyboard's layers, its smart modifier keys, its firmware and its device protocol, and can therefore offer a panel that reflects the real hardware rather than a general approximation.
The second comparison is with editing the configuration files directly. That is what the QMK firmware itself expects, since the firmware reads the same files. The UHK is unusual in shipping an open firmware, and the repository's rules/ and smart-macro-docs/ directories suggest the configuration format and the macro language are documented in the repository itself. Editing the files by hand is entirely possible and gives full control, and it is also exactly the kind of work a graphical application exists to avoid.
The third comparison is with the vendor's own tool, if the keyboard had one. For most keyboards the configurator is a closed binary, and the reason an open firmware matters is that it makes the configuration format inspectable, which is what makes a third-party or first-party open application possible at all.
Licence, project state and what to check before you build it
The licence field on the repository records a custom licence that GitHub cannot classify, and the package.json defers to the LICENSE file with See in LICENSE. For an application that a commercial vendor ships alongside a product, that licence is worth reading in full before you contribute, and it is a different arrangement from a permissive licence that any contributor could assume.
The project is not archived and the last push was on 2026-10-19, so it is actively worked on, and the release cadence of v11.0.0, v10.1.0 and v10.0.0 across 2026 shows regular shipping rather than an occasional drop.
Four things to check before you build it from source.
The Node and npm versions. The package.json engines field is narrow, and a check-node-version dependency is there to enforce it, so the mismatch between the README's Node 20 advice and the declared range of Node 24.18.1 to below 25 will stop you at install time.
The native dependencies. libusb on the host, and node-hid and serialport in the tree, so the build needs a toolchain and the runtime needs the USB libraries the operating system expects.
The device interaction. The application talks to the keyboard over USB HID and a serial port, so the web build is a demonstration of the interface and not of the hardware path, and any automation that has to run in CI has to work without the device.
And the version combination. Because the firmware version, the device protocol version and the config versions are tracked separately in the package.json, a build that pairs an old application with a new firmware can behave differently from the same application with the firmware it was written for, and that is the thing to check when a behaviour does not match what you expect.
Editorial conclusion
Agent suits an owner of the Ultimate Hacking Keyboard who wants to edit the keymap, the layers and the macros in a graphical interface rather than in text files, and who wants to see the firmware-level effect of a change. It is the wrong tool for a keyboard without the hardware, since the README says the application will not get past the opening screen, and the wrong choice for a different vendor's board. Before building from source, read the version constraints in package.json, because the declared Node and npm ranges are narrow and the installation section assumes an older Node than the one the build requires.
Frequently asked questions
What is the UHK Agent application?
It is the configuration application of the Ultimate Hacking Keyboard, an Electron and TypeScript desktop program for editing the keyboard's keymap, layers and macros. A web build is also published for demonstration, though the desktop application requires the physical keyboard to get past the opening screen.
How do I build UHK Agent from source?
Install the native dependencies, including libusb and the udev development package on Debian-based systems, then clone the repository and run npm run install, npm run build and npm run electron. The npm run install script wraps npm ci with scripts ignored and then the postinstall step, as a workaround for npm's tightening of install scripts.
What do the version numbers in the UHK Agent package.json mean?
Alongside the application version there are separate versions for the firmware, the device protocol, the user config format and the hardware config format, each of which changes at a different rate, so a reader can tell which combination of application and firmware is expected.
How do I develop the web version of UHK Agent?
The front end lives in packages/uhk-web/, and running npm run server:web serves it at http://localhost:8080 with automatic reload on change. The repository also explains that npm workspace installs run in hoisted mode, which does not suit the project, so dependencies of an individual package should be installed from that package's own directory.
What licence does UHK Agent use?
The licence field on the repository records a custom licence that GitHub cannot classify, and the package.json points to the LICENSE file with See in LICENSE, so the file holds the actual terms.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ultimatehackingkeyboard-agent)Was this useful?