Keymap Image Generator

Choose a keymap file or grab the mapping directly from your keyboard, choose the layers you want to show, choose a style you like, and download the image. Your keymap stays on your computer: this page reads it in your browser only.

Alternatively, download this repository: it includes a script you can run on your own computer to regenerate the image or images whenever you want (the Command section at the foot writes the command for you).

Theme

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.

or drop it here

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.

    
        
    If more than one Vial keyboard is plugged in, add --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.

    Sample image (not a preview of your keymap)
    Your keymap
    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.css is the simplest) to styles/<name>.css, using lower-case letters, digits and underscores, for example styles/sepia.css.
    • Make the first line a comment with a short description: /* Sepia: brown ink on cream, for printing. */. python keymap-imgen.py --list prints it.
    • Edit the colours in the :root block (--bg, --card, --ink, --acc, --heldbg and the rest) and the four font stacks. Every part of the picture has a class name and can be restyled by it; styles/README.md lists the classes and tokens.
    • Fonts: put the .woff2 file in fonts/ and reference it as url('fonts/<file>') in an @font-face rule. 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 as docs/gallery/sepia.webp, then run python keymap-imgen.py --refresh-page so the page lists it.

    Picture

    Opens once a keymap has been read above.

    Image size:

    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.

    Your computer:

    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
    If you skip this, the command stops and prints these same two lines. Details in the README, section "Playwright".

    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 .vil from Vial or a keymap.json from QMK, each with an optional <name>.settings.json beside it (this page writes those).
    • output/: the pictures. One .html and one .png per keymap and style.
    • boards/: the shapes. qmk-index.json.gz is a compressed copy of QMK's keyboard data ( boards as of ). Every other .json file in the folder is one board, written by hand or read from a keyboard over USB.
    • styles/: one .css file per style. _base.css sets 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.js is its behaviour. docs/ also holds the sample pictures and the lists the page reads: boards.js for QMK's boards by name (loaded when a name is first searched for), boards-local.js for the board files and styles that ship with it, and boards-user.js for the ones you add. Key positions come from boards/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.py and vilimg/: 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 rewrites boards/qmk-index.json.gz and docs/boards.js.
    • If you add or edit a file in boards/ by hand, or add a style sheet to styles/, run python keymap-imgen.py --refresh-page. It rewrites docs/boards-user.js, the list of board files and styles you added, which this page reads on top of the shipped list. --save-board rewrites that file as well. The file is yours: keep it across updates, and a new --refresh-page writes it again from boards/ and styles/ at any time.
    • Reload this page after either command. The browser reads both lists only when the page loads. python keymap-imgen.py --version prints 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 in docs/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.