Skip to main content

The simulator

The Kog simulator is the same native runtime (LVGL, the JS engine, the Kog host layer) compiled for your desktop, running the same app bundle your board would run. (The simulator compiles the bundle when it loads it; the board receives it as precompiled bytecode. The engine is the same.) It is not a preview or a web approximation. If it works in the sim, the rendering and logic are identical on hardware.

Using it​

npm run dev # opens the simulator automatically (default target)
npx kog build && npx kog simulate dist/app.mjs # simulator without the dev server

The window matches your configured board (board: in kog.config.ts, or --board <slug>): its resolution, HiDPI scale, and display shape, so round displays render round. Without a board, simulator.width/height in kog.config.ts set the size.

Getting a window on macOS​

Homebrew's sdl2 is now sdl2-compat (the SDL2 API implemented over SDL3), which loads libSDL3.dylib at runtime. If it can't find SDL3 on the dynamic-load path, the simulator falls back to headless instead of hanging. It still runs (hot reload, console.log, and tests all work); it just doesn't open a window, and it tells you so. To get a visible window, put SDL3 on the load path:

DYLD_LIBRARY_PATH=/opt/homebrew/lib kog dev # or DYLD_LIBRARY_PATH=$(brew --prefix)/lib

Pass --headless to skip the window on purpose (CI, over SSH, or when you only need the logs).

  • Pointer: mouse acts as the touchscreen.
  • Hot reload: identical to device. Save and it remounts in under a second. Each reload is a fresh mount, so component state and the current route start over.
  • console.log: appears in your kog dev terminal.
  • Errors: compile errors and uncaught runtime errors (with their stack) appear in your kog dev terminal.

Virtual hardware​

GPIO, ADC, and PWM work in the simulator against a virtual pin table:

  • Number keys toggle configured digital input pins (so useButton(0, ...) is testable by pressing 0).
  • The dev server can script pin and ADC values (setPin, setAdc) over the dev channel, which is useful in tests.
  • I2C/SPI transactions resolve through the same async path as real hardware, returning mock responses you can register.
  • Device services (battery, brightness, motion sensors, vibration) run against a virtual battery, backlight, motor and IMU. In the desktop window, B/Shift+B move the battery 10 %, C toggles charging, the arrow keys tilt the accelerometer (L lays it flat) and G spins the gyroscope; brightness dims the window and a running motor shows [vibrating] in the title. Studio's Simulated hardware panel has the same controls.

This means an app that reads a sensor and reacts to a button can be developed end-to-end before your board arrives.