Keymap
Export it from Vial (File → Save current layout) or from QMK Configurator (Export keymap), and keep a copy
in the keymaps/ folder. Or plug in a Vial keyboard and read it straight from the board.
The printed letters follow the US layout: on a QWERTZ, AZERTY, Spanish or JIS keyboard the picture shows the US legend for each key.
No keymap yet? Try a sample keymap of a 60% keyboard, or a split 40% keyboard to see what the page does.
Plug in a Vial keyboard: its shape and mapping are read from the board (nothing is written to it).
Works in Chrome, Edge and other Chromium browsers;
on Linux the board also needs
Vial's udev rule (the same one the Vial app uses).
Keyboard
Opens once a keymap has been read above.
Usually found from your keymap file. If it is wrong or missing, type part of the name
(corne, sofle, planck) and pick yours. Not there? Draw a plain grid, or read the
shape from your keyboard (advanced, below).
Advanced (local install only): board files, and reading the shape from your keyboard over USB
A keymap file holds no physical layout, only the key matrix. A board file lists the position of every key: the generator reads
boards/<name>.json, and the name without .json is what goes after --board.
There are three ways to get one.
1. Read it from the keyboard (Vial firmware, including clones and kits with extra keys). Vial firmware contains a
drawing of the board it runs on. Plug the keyboard in, give it a short name, and run the two lines below in a terminal opened in the keymap-imgen folder.
The first installs the USB library, once. The second reads the drawing (read-only, the same request the Vial app makes when
you plug in) and saves it with the board's uid, so its .vil files are recognised from then on and it appears in the
search list above after you reload this page. A vial.json copied from a firmware repository is not read directly.
Linux needs a udev rule first; the README section "Clones and boards with extra keys" contains it.
--device 1 (or 2, ...) to the second line.2. QMK keyboards: no file needed. Every keyboard in QMK's data is in the search list above with all of its layouts,
and keymap.json exports already contain the keyboard's name. A QMK info.json or keyboard.json
is not read directly. If your board was added to QMK after the refresh date, use the USB route (Vial firmware) or write a file.
3. By hand. Copy boards/corne42.json and edit it. Each key has its matrix position ([row, col],
the same numbers as in the .vil arrays), its x and y in key units, and optional
w, h and a rotation r about rx, ry (the QMK convention).
Name it with lower-case letters, digits and dashes, for example boards/mycorne.json, then run
python keymap-imgen.py --refresh-page so this page lists it. boards/README.md in the folder has the
full description.
Layers
Opens once a keymap has been read above.
Tick the layers you want in the picture. Labels are optional.
Image style
Opens once a keymap has been read above.
Pick a style. Most come in a dark and a light version; the picture shows the one under your pointer. Click the picture to see it large."View large" shows the drawn sheet at full size.
Advanced (local install only): add your own style
A style is one CSS file in the styles/ folder; its file name is the style name.
- Copy the one closest to what you want (
styles/plain.cssis the simplest) tostyles/<name>.css, using lower-case letters, digits and underscores, for examplestyles/sepia.css. - Make the first line a comment with a short description:
/* Sepia: brown ink on cream, for printing. */.python keymap-imgen.py --listprints it. - Edit the colours in the
:rootblock (--bg,--card,--ink,--acc,--heldbgand the rest) and the four font stacks. Every part of the picture has a class name and can be restyled by it;styles/README.mdlists the classes and tokens. - Fonts: put the
.woff2file infonts/and reference it asurl('fonts/<file>')in an@font-facerule. The renderer embeds it into the HTML, so the output stays a single file. Only bundle fonts whose licence allows redistribution. - The new style can be used at once:
python keymap-imgen.py sepia, or type its name in the box below. To give it a picture on this page, render the sample and save a small copy asdocs/gallery/sepia.webp, then runpython keymap-imgen.py --refresh-pageso the page lists it.
Picture
Opens once a keymap has been read above.
Safari cannot turn the drawn page into a PNG (its canvas refuses HTML content). Download the SVG instead, or use Chrome, Edge or Firefox for the PNG.
The SVG is one file per sheet, fonts included, and stays sharp at any size. A browser opens it and draws it exactly as this page does; the sheet inside is HTML, which most vector editors cannot read.
Command
Opens once a keymap has been read above.
Prefer the command line? A downloaded copy makes the same picture from this command
Everything chosen above (keymap, keyboard, layers, style, picture options) is written into one command.
Run it in the keymap-imgen folder and the same picture is drawn; run it again after a keymap change and
the picture is redrawn.
Open a terminal in the keymap-imgen folder and paste this:
python keymap-imgen.py plain
The pictures land in the output/ folder: one HTML page per keymap and style, and a PNG beside
it unless you turned the PNG off.
First time: install Playwright (once, about 150 MB)
The command line draws with a headless browser, Playwright, which is installed once. Copy these two lines into the same terminal and run them before the command above:
python -m pip install playwright python -m playwright install chromium
How to open a terminal in a folder. Windows: click the address bar of the folder in File Explorer, type
cmd, press Enter. macOS: right-click the folder in Finder, then Services, New Terminal at Folder. Linux: most
file managers have "Open in Terminal" in the right-click menu.
What the settings file does
"Save settings file" writes <keymap name>.settings.json with the keyboard, layers, layer names and
title chosen above. Put it in keymaps/ beside the keymap. From then on python keymap-imgen.py with
nothing after it renders every keymap in keymaps/ in plain, the default style, reading each
keymap's settings file on the way, and writes the pictures to output/. A style name after
keymap-imgen.py picks another style; a file name after it renders that one file. The picture options (PNG or
not, dual monitor, split halves) are not stored in the settings file: they stay on the command line.
Rerun with a double-click (Windows)
Open keymap-imgen.bat in the keymap-imgen folder in Notepad, replace its python keymap-imgen.py line with your
command, and save. Double-clicking the file then runs it. As shipped, the file renders every keymap in keymaps/
in the default style.
How the image generator is put together
The generator is a folder of plain files, and each part can be read, replaced or extended on its own. The full description is in the README; this is the list of folders.
keymaps/: your keymap files, a.vilfrom Vial or akeymap.jsonfrom QMK, each with an optional<name>.settings.jsonbeside it (this page writes those).output/: the pictures. One.htmland one.pngper keymap and style.boards/: the shapes.qmk-index.json.gzis a compressed copy of QMK's keyboard data ( boards as of ). Every other.jsonfile in the folder is one board, written by hand or read from a keyboard over USB.styles/: one.cssfile per style._base.csssets the positions and sizes of everything on the page; the others set colours and fonts.fonts/: the font files that are embedded into the pages, all under licences that allow it.index.html: this page;docs/page.jsis its behaviour.docs/also holds the sample pictures and the lists the page reads:boards.jsfor QMK's boards by name (loaded when a name is first searched for),boards-local.jsfor the board files and styles that ship with it, andboards-user.jsfor the ones you add. Key positions come fromboards/qmk-index.json.gz, fetched and decompressed by the page when it is opened over http.docs/vilimg.js: the code that draws the pictures (legends, layer text, page layout), shared by this page and the command line.keymap-imgen.pyandvilimg/: the command line around it, which runs that file in Playwright's browser;tools/holds the maintenance scripts.
Refreshing the board list.
- The QMK data in the folder is a copy made on . Keyboards added to QMK after that date are not in it. Nothing is downloaded when a command runs; every shape comes from the files above.
- To refresh the copy, run
python tools/build_qmk_index.py. It downloads the current list from keyboards.qmk.fm, takes about ten minutes, and can be run again to continue if it was interrupted. It rewritesboards/qmk-index.json.gzanddocs/boards.js. - If you add or edit a file in
boards/by hand, or add a style sheet tostyles/, runpython keymap-imgen.py --refresh-page. It rewritesdocs/boards-user.js, the list of board files and styles you added, which this page reads on top of the shipped list.--save-boardrewrites that file as well. The file is yours: keep it across updates, and a new--refresh-pagewrites it again fromboards/andstyles/at any time. - Reload this page after either command. The browser reads both lists only when the page loads.
python keymap-imgen.py --versionprints the refresh date of the QMK data.
Where to change things.
- If a key shows its raw keycode (for example
KC_WEIRD) instead of a label, the label tables indocs/vilimg.js(the legends section) do not have an entry for that keycode. Add one there. - If the line under a layer's title (for example "Hold left middle thumb") names the wrong key, the position rules in
docs/vilimg.js(the layers section) are wrong for this board's geometry. The rules are described there. - To change how a picture looks, edit or add a CSS file in
styles/; see Image style above. - To change where keys are drawn, edit or add a JSON file in
boards/; see Keyboard above.