Flash your board
The first time you connect a board, Kog performs a one-time setup: it downloads the prebuilt Kog runtime firmware for your chip and flashes it. After that, deploying your app takes about a second — only the tiny app bundle moves.
You don't need the CLI to get Kog onto a board. The Run on your board page flashes and hot-reloads a blessed board entirely from Chrome or Edge over Web Serial — no CLI, no Python, no toolchain. This guide covers the CLI path, which you'll want once you're developing locally.
First flash
npm run flash # from a scaffolded project
# or directly:
npx kog flash
What happens:
- Detection — the CLI scans USB serial ports and identifies your board by its USB identifiers and chip handshake. ESP32-S3/C3/C6 boards use native USB and need no drivers on macOS, Windows, or Linux.
- Runtime download — the prebuilt runtime image matching your chip, memory configuration, and CLI version is fetched (a few MB) and cached.
- Flash — bootloader, partition table, runtime, and board configuration are written in one pass, each part verified against its SHA-256 before it's written. Flashing is implemented in pure Node (no Python, no
esptoolinstall). - Wi-Fi handoff (optional) — while still connected over USB,
npm run wifihands the device your Wi-Fi credentials so future development can be wireless.
Typical first-flash time: under a minute. After that, npm run dev skips straight to pushing your app bundle (~1 second), and npm run deploy installs a build as the device's standalone app.
USB drivers
Most boards enumerate as a USB serial port the moment you plug them in. Which driver (if any) you need depends on the USB-to-serial bridge on the board:
| Bridge chip | USB vendor ID | Driver | Boards |
|---|---|---|---|
| Espressif native USB | 303a | None — built into the OS | ESP32-S3 / C3 / C6 (e.g. Waveshare 1.46B) |
| Silicon Labs CP210x | 10c4 | Usually none on modern OSes; CP210x VCP driver if the port doesn't appear | Many ESP32 dev boards |
| WCH CH340 / CH343 | 1a86 | Usually none on modern OSes; CH34x driver if the port doesn't appear | ESP32-2432S028R "Cheap Yellow Display" |
| FTDI | 0403 | Built in | Older / breakout boards |
Run kog doctor to see the serial ports Kog can find and whether a driver looks missing.
Picking the port
With one board plugged in, kog flash and kog dev auto-select it. If you have several serial devices attached (or the wrong one is chosen), name the port explicitly:
npx kog flash --port /dev/cu.usbserial-210 # macOS
npx kog flash --port COM5 # Windows
npx kog flash --port /dev/ttyUSB0 # Linux
Ports look like /dev/cu.usbserial-* or /dev/cu.usbmodem-* on macOS, COM* on Windows, and /dev/ttyUSB* / /dev/ttyACM* on Linux.
Troubleshooting
| Symptom | Most likely cause | Fix |
|---|---|---|
| No board found / port list empty | driver or cable | Install the driver for your bridge chip (table above); try a different USB cable — some are charge-only |
| ESP32-S3 board missing from the list | wrong USB port | Use the board's native USB-C port, not a separate UART header |
sync-failed / chip won't respond | auto-reset didn't enter the bootloader | Unplug and replug; some CYD clones need the BOOT button held while connecting |
verify-mismatch on a part | corrupted download or a stale cache | Re-run the flash; the SHA-256 check is doing its job — it refuses to write a bad image |
| Flashes fine but the screen stays blank | app slot empty on first flash | Expected — push an app with npm run dev (hot reload) or npm run deploy (standalone) |
| CYD screen is left/right mirrored and blue UI renders orange | classic panel generation (same silkscreen, different glass) | Reflash with npx kog flash --board cyd-classic — see below |
AbiMismatch when pushing an app | device runtime is older than your CLI | Re-flash the runtime: npx kog flash --runtime (your app and settings are preserved) |
Two kinds of CYD
The ESP32-2432S028R ships two panel generations behind the same silkscreen — standard glass
(cyd) and the older ILI9341-generation glass (cyd-classic, BGR color order + mirrored scan,
typically the micro-USB-only units). They're indistinguishable from the outside and over USB, so
the CLI asks you to pick when it can't tell:
npx kog flash --board cyd # try this first
npx kog flash --board cyd-classic # if the screen came up mirrored with orange-instead-of-blue UI
The symptom pair IS the identification: on the wrong image the UI is crisp and touch works, but everything is left/right mirrored and colors that should be blue render orange. Nothing is damaged by trying the other image — flash back and forth freely. The browser flasher offers the same two choices when it detects a plain ESP32.
Flashing from the browser instead? The Run on your board page has its own troubleshooting for Web Serial, and the same driver notes apply.
When the runtime updates
Your app bundle declares the runtime ABI it was built against, and the CLI checks the device before pushing. If they've drifted apart you'll see exactly what to do:
Device runtime is ABI 3; your Kog CLI builds ABI 4.
Run `kog flash --runtime` to upgrade the board (your app and settings are preserved).
Development vs. production
A board is in one of two postures, and the command you run picks it:
- Development — what
kog flash(andkog dev) leave the board in. The runtime reserves a small dev-link channel sokog devcan hot-reload your code over USB in about a second. Hot reload is USB-only — there's no Wi-Fi/network code-push; a board's Wi-Fi is for your app's own networking. - Production — what
kog deploysets. It installs your app as the board's standalone program (signed, with rollback if it fails to boot), turns hot reload off, and gives the full RAM to your app — a deployed board has no code-push channel. To develop on that board again, just runkog flash.
Kog runs a single JavaScript engine, MQuickJS, so every prebuilt image — the CYD and the Waveshare/ESP32-S3 alike — ships it. MQuickJS runs your app's bytecode in place from read-only flash rather than copying it into the JS heap, which is what lets even a PSRAM-less board like the CYD keep a running app and the hot-reload dev-link in RAM at once (~95 KB free — enough for networking and the dev-link together). The CYD prebuilt is validated on hardware.
You don't have to think about any of this. kog dev and kog deploy read the connected board's runtime over the live link and confirm your app is compiled for it (you'll see a Board runs mquickjs (bcv 44283) line). A board still on the retired quickjs-ng firmware is detected too — you'll be told to reflash it (kog flash) to the MQuickJS runtime, then retry. Everything else — the same source, the same @kog/ui, the same workflow — is identical everywhere.
Which boards work?
- Blessed boards (tested by us, prebuilt images hosted): see Boards. The reference targets are the Waveshare ESP32-S3-Touch-LCD-1.46B and the ESP32-2432S028R "Cheap Yellow Display".
- Any board with supported display/touch controllers: works with the generic prebuilt image plus a
board.yamldescribing your wiring — still no compiling. - Anything else:
kog firmware buildcompiles a custom runtime from yourboard.yaml, auto-installing a managed toolchain. You still never leave the Kog workflow. See Boards & custom hardware.
The CYD (ESP32-2432S028R, cyd) and Waveshare ESP32-S3-Touch-LCD-1.46B prebuilts are validated on real hardware — flash, hot-reload, and deploy confirmed on-glass, running the MQuickJS engine. The cyd-classic prebuilt was diagnosed from a real classic-panel unit (its display quirks are the only difference from cyd) but is not yet hardware-validated end-to-end; flashing it writes the same SHA-verified images, and you can always return to cyd by reflashing.