Skip to content

Configuration

Complete reference for HelixScreen configuration options.



PlatformLocation
MainsailOS (Pi)~/helixscreen/config/settings.json (or /opt/helixscreen/config/ if no Klipper ecosystem)
AD5M Forge-X/opt/helixscreen/config/settings.json
AD5M Klipper Mod/root/printer_software/helixscreen/config/settings.json
K1 Simple AF/usr/data/helixscreen/config/settings.json
Development./config/settings.json (in config/ directory)

Note: On Pi, the installer auto-detects your Klipper ecosystem. If ~/klipper, ~/moonraker, or ~/printer_data exists, HelixScreen installs to ~/helixscreen. Otherwise it falls back to /opt/helixscreen. You can override with INSTALL_DIR=/path ./install.sh.

The configuration file is created automatically by the first-run wizard. You can also copy from the template:

Terminal window
cp config/settings.json.template config/settings.json

Note: Legacy config locations (settings.json in app root or /opt/helixscreen/settings.json) are automatically migrated to the new location on startup.


The configuration file is JSON format with several top-level sections:

{
"dark_mode": false,
"brightness": 50,
"sounds_enabled": true,
"completion_alert": 2,
"wizard_completed": false,
"wifi_expected": false,
"language": "en",
"beta_features": false,
"log_dest": "auto",
"log_path": "",
"log_level": "warn",
"panel_widgets": { ... },
"theme": { ... },
"display": { ... },
"input": { ... },
"output": { ... },
"network": { ... },
"printer": { ... },
"gcode_viewer": { ... },
"ams": { ... },
"cache": { ... },
"streaming": { ... },
"safety": { ... },
"filament_sensors": { ... },
"plugins": { ... },
"update": { ... }
}

When multiple printers are configured, the config file uses a versioned schema (v4) with per-printer settings:

{
"config_version": 4,
"active_printer_id": "voron-24",
"printers": {
"voron-24": {
"printer_name": "Voron 2.4",
"moonraker_host": "192.168.1.100",
"moonraker_port": 7125,
"wizard_completed": true,
"printer_image": "shipped:voron-24r2",
...per-printer settings...
},
"ender-3": {
"printer_name": "Workshop Ender",
"moonraker_host": "192.168.1.101",
"moonraker_port": 7125,
"wizard_completed": true,
...per-printer settings...
}
},
"wifi": { ... },
"display": { ... }
}

Each printer entry contains all printer-specific settings (connection details, hardware selections, LED config, filament sensors, etc.). Device-level settings like WiFi and display preferences remain at the root level and are shared across all printers.

Note: You don’t need to edit the config file manually — use the Settings > Printers UI to add and manage printers. The config file is shown here for reference.


Looking for a walkthrough of each setting? See the detailed guides: Display & Sound · Printing · Hardware & Devices · Safety & Notifications · System · LED Settings · Help & About

Type: boolean Default: false Description: Use dark theme (true) or light theme (false). Can also be set via Settings panel or --dark/--light CLI flags.

Type: integer Default: 50 Range: 1 - 100 Description: Screen brightness percentage. Adjustable via Settings panel.

Type: boolean Default: true Description: Enable UI sound effects (button clicks, navigation sounds).

Type: integer Default: 2 Values: 0 (Off), 1 (Notification), 2 (Alert) Description: How HelixScreen notifies you when a print completes or is cancelled (while you’re on a different screen):

  • 0Off: No notification (sound still plays if sounds are enabled)
  • 1Notification: Brief toast message at the top of the screen
  • 2Alert: Full-screen modal with print stats (duration, layers, filament used) and confetti for successful prints

Errors always show the full alert regardless of this setting. To change this in the UI, go to Settings > Print Complete Alert and select from the dropdown.

Type: boolean Default: false Description: Disable all sound output entirely. Prevents the audio backend from initializing, which avoids CPU overhead on hardware where audio drivers are present but unusable (e.g., Artillery M1 Pro). Also available as the --no-sound CLI flag.

This is different from sounds_enabled — that toggle mutes playback but still initializes the audio backend. disable_sound prevents initialization altogether.

Type: boolean Default: false Description: Whether the setup wizard has been completed. Set automatically after first-run wizard. Set to false to re-trigger the wizard on next startup.

Type: boolean Default: false Description: Whether WiFi connectivity is expected. When true, HelixScreen shows connection warnings if WiFi is unavailable. Set during the wizard based on your network configuration choice.

Type: string Default: "en" Values: "en" (English) Description: UI language code. Currently only English is supported.

Type: boolean Default: false Description: Enable beta features that are still under testing. Gates several Advanced panel features (Macro Browser, Input Shaping, Z-Offset Calibration, HelixPrint plugin management, PRINT_START configuration, Timelapse), the Plugins section in Settings, and the Update Channel selector. Always enabled automatically when running in --test mode. Can also be toggled by tapping the version button 7 times in Settings → About. See the Beta Features section in the User Guide for the full list.


Located in the theme section:

{
"theme": {
"preset": 0
}
}

Type: integer Default: 0 Description: Theme accent color preset. Requires restart to take effect.

ValueTheme
0Ayu
1Catppuccin
2ChatGPT
3Cupertino
4Dracula
5Everforest
6Gruvbox
7HelixScreen
8Kanagawa
9Material Design
10Midnight
11Nord (default)
12One Dark
13Rose Pine
14Solarized
15Tokyo Night
16Yami

Tip: You can also browse and apply themes visually in Settings > Appearance > Display Settings > Theme Colors.


Type: string Default: "auto" Values: "auto", "journal", "syslog", "file", "console" Description: Log destination:

  • auto - Detect best option (journal on systemd, console otherwise)
  • journal - systemd journal (view with journalctl -u helixscreen)
  • syslog - Traditional syslog
  • file - Write to log file
  • console - Print to stdout/stderr

Type: string Default: "" Description: Path for log file when log_dest is "file". Empty uses default location:

  • /var/log/helix-screen.log (if writable)
  • ~/.local/share/helix-screen/helix.log (fallback)

Type: string Default: "warn" Values: "warn", "info", "debug", "trace" Description: Log verbosity level:

  • warn - Quiet, only warnings and errors (default)
  • info - General operational information
  • debug - Detailed debugging information
  • trace - Extremely verbose, all internal operations

Note: This can also be changed at runtime via Settings > System > Log Level without restarting. CLI -v flags override this setting (-v=info, -vv=debug, -vvv=trace).


Located in the display section:

{
"display": {
"animations_enabled": true,
"time_format": 0,
"rotate": 0,
"sleep_sec": 1800,
"dim_sec": 300,
"dim_brightness": 30,
"drm_device": "",
"gcode_render_mode": 2,
"gcode_3d_enabled": true,
"bed_mesh_render_mode": 0,
"bed_mesh_show_zero_plane": true,
"printer_image": "",
"calibration": {
"valid": false
}
}
}

Type: boolean Default: true Description: Enable UI animations and transitions. Disable for better performance on slow devices.

Type: integer Default: 0 Values: 0 (12-hour), 1 (24-hour) Description: Time display format. 0 shows “2:30 PM”, 1 shows “14:30”.

Type: integer Default: 0 Values: 0, 90, 180, 270 Description: Rotate the entire display by the specified degrees. Touch coordinates are automatically adjusted to match.

Automatic detection: On first boot, HelixScreen checks the kernel for panel orientation (e.g., panel_orientation=upside_down in the kernel command line). If detected, the rotation is applied immediately and saved here — no manual configuration needed. On framebuffer displays only (e.g., AD5M — not Raspberry Pi), an interactive rotation wizard runs instead if no kernel hint is found.

Performance note (Raspberry Pi / DRM displays): When rotation is active on DRM-based displays (Pi 4, Pi 5), HelixScreen uses a software rotation approach that redraws the full screen on every frame update instead of only the changed regions. This adds a small overhead (typically <1ms per frame on Pi 5) but is necessary because the LVGL DRM driver does not support hardware rotation. Framebuffer displays (e.g., AD5M) use a more efficient partial-update rotation with no meaningful performance impact.

Type: boolean Default: false Description: Set to true after automatic rotation detection runs. Remove this key (along with rotate) to re-trigger automatic detection on next startup.

Type: integer Default: 1800 Description: Seconds of inactivity before screen turns OFF. Set to 0 to disable sleep. Default is 30 minutes.

Type: integer Default: 300 Description: Seconds of inactivity before screen dims. Set to 0 to disable dimming. Must be less than sleep_sec. Default is 5 minutes.

Type: integer Default: 30 Range: 1 - 100 Description: Brightness percentage when screen is dimmed.

Type: string Default: "" (auto-detect) Example: "/dev/dri/card1" Description: Override DRM device for display output. Leave empty for auto-detection.

Pi 5 DRM devices:

  • /dev/dri/card0 - v3d (3D only, no display output)
  • /dev/dri/card1 - DSI touchscreen
  • /dev/dri/card2 - HDMI (vc4)

Auto-detection finds the first device with dumb buffer support and a connected display.

Type: integer Default: 2 Values: 0 (Auto/2D), 2 (2D Layer) Description: G-code visualization mode:

  • 0 - Auto (currently uses 2D)
  • 2 - 2D Layer view (default, recommended)

Can also be overridden via HELIX_GCODE_MODE env var (3D or 2D).

Type: boolean Default: true Description: Enable 3D G-code preview capability. When false, only 2D layer view is available.

Type: integer Default: 0 Values: 0 (3D surface), 1 (2D heatmap) Description: Bed mesh visualization mode. 3D surface shows the mesh as a 3D plot, 2D heatmap shows it as a flat color grid.

Type: boolean Default: true Description: Show translucent reference plane at Z=0 in bed mesh 3D view. Helps visualize where the nozzle touches the bed.

Type: string Default: "" (auto-detect) Description: Printer image displayed on the Home Panel and in the Printer Manager. The value determines which image is used:

  • "" (empty string or absent) — Auto-detect: HelixScreen selects an image based on the printer type reported by Klipper
  • "shipped:voron-24r2" — Use a specific shipped image by name (see assets/images/printers/ for available images)
  • "custom:my-printer" — Use a custom image that was imported from config/custom_images/

Custom images are PNG or JPEG files placed in config/custom_images/. They are automatically converted to optimized LVGL binary format (300px and 150px variants) when the Printer Image picker overlay is opened. Maximum file size is 5MB, maximum resolution is 2048x2048 pixels.

This setting can also be changed via the Printer Manager overlay (tap the printer image on the Home Panel).

Type: object Default: {"valid": false} Description: Touch calibration coefficients. Set by the calibration wizard or manually. Contains calibration matrix values (a through f) when valid. If the wizard auto-detects that the touchscreen’s X/Y axes are swapped relative to the display, it also saves "swap_axes": true — this is applied automatically on startup.


Located in the input section:

{
"input": {
"scroll_throw": 25,
"scroll_limit": 10,
"jitter_threshold": 5,
"scroll_guard": false,
"scroll_guard_cooldown_ms": 80,
"touch_device": "",
"force_calibration": false
}
}

Tuning touch feel: These four settings interact. See Touch Feel — Which Setting Do I Tune? in the troubleshooting guide for a symptom → setting map.

Type: integer Default: 25 Range: 5 - 50 (UI-clamped) Description: Scroll momentum decay rate — how quickly a flicked list coasts to a stop. Higher values = faster decay (less “throw”). LVGL’s native default is 10; we use 25 because touchscreens feel sluggish with long coasting. Lower it if lists feel too “sticky” at the end of a flick.

Type: integer Default: 10 Range: 1 - 20 (UI-clamped) Description: Pixels of finger movement required before a gesture is treated as a scroll instead of a tap. Below this threshold LVGL still thinks you’re pressing a widget, and releasing will fire a click. Above it, the press is cancelled and scroll engages.

  • Lower = scroll engages sooner. Fixes phantom clicks that fire when scrolling a list with a short, slow swipe.
  • Higher = more deliberate gesture required. Reduces accidental scrolls when you meant to tap, but makes short-travel scrolls feel unresponsive.

Matches LVGL’s native default of 10.

Type: string Default: "" (auto-detect) Example: "/dev/input/event1" Description: Override touch/pointer input device. Leave empty for auto-detection. Auto-detection finds touch or pointer capable devices.

Type: integer Default: 5 Range: 0 - 200 Description: Touch jitter filter dead zone in pixels. Capacitive touch controllers (notably Goodix GT9xx on FlashForge displays) report 2–5 px of coordinate drift even with a stationary finger. Without filtering, that drift accumulates past scroll_limit and a stationary tap gets cancelled as if it were a scroll. The filter freezes reported coordinates to the initial press point while movement stays within this radius.

  • Raise if stationary taps are still being misread as swipes or scrolls on a noisy panel (typical fix: 15–25).
  • Lower / 0 if the filter is suppressing intentional short-travel gestures.

Can also be overridden with the HELIX_TOUCH_JITTER environment variable.

Type: boolean Default: false (overridden to true by AD5M/AD5X presets) Description: Suppresses the phantom “clicked” event some capacitive touch controllers generate when the finger lifts at the end of a scroll gesture. Common on FlashForge AD5M and AD5X displays — you scroll a list, lift your finger, and whatever button is now under where your finger was fires. When enabled, HelixScreen ignores taps for the cooldown window (default 80 ms — see scroll_guard_cooldown_ms) after a scroll ends. Can also be overridden with the HELIX_SCROLL_GUARD environment variable (1 to enable).

Type: integer Default: 80 Range: 20 - 500 Description: How long (in milliseconds) scroll_guard suppresses taps after a scroll gesture ends. Only takes effect when scroll_guard is enabled. The default handles most capacitive controllers that re-press briefly during lift-off; if you still see phantom clicks right as you lift your finger, try raising to 150 or 200. Going too high will swallow legitimate taps that closely follow a scroll, so raise gradually. Can also be overridden with the HELIX_SCROLL_GUARD_COOLDOWN_MS environment variable.

Type: boolean Default: false Description: Force touch calibration on next startup, even if the device doesn’t normally require it. After successful calibration, this flag is automatically cleared. Useful when touch input is inaccurate but HelixScreen doesn’t show the calibration option in Settings.


Located in the output section:

{
"output": {
"led_on_at_start": false
}
}

Type: boolean Default: false Description: Automatically turn on the configured LED strip when Klipper becomes ready. Useful for printers with chamber lights that should always be on. Deprecated: This setting has moved to printer.leds.led_on_at_start. The legacy location is still read for backward compatibility.


Located in the network section:

{
"network": {
"connection_type": "None",
"wifi_ssid": "",
"eth_ip": ""
}
}

Type: string Default: "None" Values: "None", "wifi", "ethernet" Description: Current network connection type.

Type: string Default: "" Description: Connected WiFi network SSID.

Type: string Default: "" Description: Ethernet IP address (when connected).


Located in the printer section:

{
"printer": {
"name": "Unnamed Printer",
"type": "Unknown",
"moonraker_host": "192.168.1.112",
"moonraker_port": 7125,
"moonraker_api_key": false,
"heaters": {
"bed": "heater_bed",
"hotend": "extruder"
},
"temp_sensors": {
"bed": "temperature_sensor bed",
"hotend": "temperature_sensor extruder"
},
"fans": {
"hotend": "heater_fan hotend_fan",
"part": "fan",
"chamber": "",
"exhaust": ""
},
"leds": {
"strip": "",
"selected_strips": [],
"led_on_at_start": false,
"last_color": 16777215,
"last_brightness": 100,
"color_presets": [16777215, 16711680, 65280, 255, 16776960, 16711935, 65535],
"auto_state": { ... },
"macro_devices": []
},
"extra_sensors": {},
"hardware": {
"optional": [],
"expected": [],
"last_snapshot": {}
},
"default_macros": { ... },
"safety_limits": { ... },
"capability_overrides": { ... }
}
}

Breaking Change (Jan 2026): The config schema changed from singular keys (heater, sensor, fan, led) to plural keys (heaters, temp_sensors, fans, leds). If upgrading from an older version, delete your config file and re-run the first-run wizard.

Type: string Default: "Unnamed Printer" Description: Display name for your printer.

Type: string Default: "Unknown" Description: Printer model/type for feature detection (e.g., “Voron 2.4”, “AD5M”, “K1”).

Type: string Default: "extruder" Description: Klipper heater name for hotend.

Type: string Default: "heater_bed" Description: Klipper heater name for heated bed.

Type: string Description: Temperature sensor for hotend (may differ from heater name if using separate sensor).

Type: string Description: Temperature sensor for bed (may differ from heater name if using separate sensor).

Type: string Default: "fan" Description: Klipper fan name for part cooling.

Type: string Description: Klipper fan name for hotend cooling.

Type: string Default: "" (none) Description: Klipper fan name for chamber fan (e.g., "fan_generic chamber_fan"). Leave empty if not available.

Type: string Default: "" (none) Description: Klipper fan name for exhaust fan (e.g., "fan_generic exhaust_fan"). Leave empty if not available.


Located in the printer.leds section. Configured via Settings > LED Settings.

Type: string Default: "" (empty) Description: Legacy single LED strip name. Empty string if no controllable LEDs. Superseded by leds.selected_strips for multi-strip control.

Type: array of strings Default: [] Description: Klipper LED strip IDs to control (e.g., ["neopixel caselight", "dotstar toolhead"]). Supports neopixel, dotstar, led, and WLED strips. Configured via Settings > LED Settings.

Type: boolean Default: false Description: Automatically turn on selected LED strips when Klipper becomes ready. Useful for chamber lights that should always be on. This setting has moved from output.led_on_at_start to here, though the legacy location is still read for backward compatibility.

Type: string (or integer) Default: "#FFFFFF" (white) Description: Last used LED color as a #RRGGBB hex string (e.g., "#FFFFFF" = white, "#FF0000" = red, "#00FF00" = green). Legacy integer RGB values (e.g., 16777215) are also accepted for backward compatibility. Remembered between sessions.

Type: integer Default: 100 Range: 0 - 100 Description: Last used brightness percentage. Remembered between sessions.

Type: array of strings (or integers) Default: ["#FFFFFF", "#FF0000", "#00FF00", "#0000FF", "#FFFF00", "#FF00FF", "#00FFFF"] Description: Preset colors shown in the color picker as #RRGGBB hex strings. Legacy integer RGB values are also accepted. Default presets are white, red, green, blue, yellow, magenta, and cyan.

Type: object Description: Automatic state-based LED lighting configuration. When enabled, LEDs change automatically based on printer state.

{
"auto_state": {
"enabled": false,
"mappings": {
"idle": { "action": "brightness", "brightness": 50, "color": "#000000" },
"heating": { "action": "color", "color": "#FF0000", "brightness": 100 },
"printing": { "action": "brightness", "brightness": 100, "color": "#000000" },
"paused": { "action": "effect", "effect_name": "breathing", "color": "#000000", "brightness": 100 },
"error": { "action": "color", "color": "#FF0000", "brightness": 100 },
"complete": { "action": "color", "color": "#00FF00", "brightness": 100 }
}
}
}
  • enabled — Boolean, enable/disable automatic state-based lighting
  • mappings — Object mapping printer state keys (idle, heating, printing, paused, error, complete) to actions
  • Each mapping has an action type: "off", "brightness", "color", "effect", "wled_preset", or "macro"
  • Additional fields depend on the action: brightness (0-100), color (#RRGGBB hex string or legacy integer RGB), effect_name (string), wled_preset (integer), macro (string)

Type: array of objects Default: [] Description: Custom LED macro devices shown as cards in the LED control overlay. Each device object:

{
"name": "Chamber Light",
"type": "on_off",
"on_macro": "LIGHTS_ON",
"off_macro": "LIGHTS_OFF",
"toggle_macro": "",
"presets": []
}
  • name — Display name for the device card
  • type — Device type: "on_off" (separate on/off macros), "toggle" (single toggle macro), or "preset" (multiple named presets)
  • on_macro / off_macro — Macro names for on/off type
  • toggle_macro — Macro name for toggle type
  • presets — Array of {"name": "...", "macro": "..."} objects for preset type

Configured via Settings > LED Settings > Macro Devices.

Type: object Default: {} Description: Additional temperature sensors to monitor (beyond hotend/bed). Keys are display names, values are Klipper sensor names.

Type: object Description: Hardware tracking information (managed automatically by the wizard):

  • optional - List of optional hardware detected
  • expected - List of expected hardware based on printer type
  • last_snapshot - Last hardware state snapshot for change detection

Type: object Description: G-code macros for quick-action buttons throughout the UI. Each macro can be a plain G-code string or an object with label and gcode fields.

Default values:

{
"default_macros": {
"cooldown": "SET_HEATER_TEMPERATURE HEATER=extruder TARGET=0\nSET_HEATER_TEMPERATURE HEATER=heater_bed TARGET=0",
"load_filament": { "label": "Load", "gcode": "LOAD_FILAMENT" },
"unload_filament": { "label": "Unload", "gcode": "UNLOAD_FILAMENT" },
"macro_1": { "label": "Clean Nozzle", "gcode": "HELIX_CLEAN_NOZZLE" },
"macro_2": { "label": "Bed Level", "gcode": "HELIX_BED_LEVEL_IF_NEEDED" }
}
}
KeyFormatWhere it’s used
cooldownG-code stringPreheat widget (auto-shows “Cool Down” when heaters are on), Filament panel cooldown button
load_filament{ "label", "gcode" }Filament panel Load button
unload_filament{ "label", "gcode" }Filament panel Unload button
macro_1{ "label", "gcode" }Controls panel custom button 1
macro_2{ "label", "gcode" }Controls panel custom button 2

Customizing cooldown for enclosed printers:

If your printer has a chamber heater, bed fans, or recirculation fans that should turn off during cooldown, override the cooldown macro:

{
"cooldown": "SET_HEATER_TEMPERATURE HEATER=extruder TARGET=0\nSET_HEATER_TEMPERATURE HEATER=heater_bed TARGET=0\nSET_HEATER_TEMPERATURE HEATER=chamber_heater TARGET=0\nSET_FAN_SPEED FAN=bed_fan SPEED=0"
}

Multi-line G-code is separated by \n. You can also reference a Klipper macro by name (e.g., "cooldown": "MY_COOLDOWN_MACRO").

Configured via Settings > Printer > Macro Buttons, or by editing settings.json directly.


Connection settings are in the printer section:

{
"printer": {
"moonraker_host": "192.168.1.112",
"moonraker_port": 7125,
"moonraker_api_key": false,
"moonraker_connection_timeout_ms": 10000,
"moonraker_request_timeout_ms": 30000,
"moonraker_keepalive_interval_ms": 10000,
"moonraker_reconnect_min_delay_ms": 200,
"moonraker_reconnect_max_delay_ms": 2000,
"moonraker_timeout_check_interval_ms": 2000
}
}

Type: string Default: "192.168.1.112" (template default, usually "localhost") Description: Moonraker hostname or IP address.

Type: integer Default: 7125 Description: Moonraker port number.

Type: string or false Default: false Description: API key if Moonraker authentication is enabled. Set to false if no authentication.

Type: integer Default: 10000 Description: Connection timeout in milliseconds.

Type: integer Default: 30000 Description: Request timeout for Moonraker API calls.

Type: integer Default: 10000 Description: Interval for WebSocket keepalive pings.

Type: integer Default: 200 Description: Minimum delay before reconnection attempt.

Type: integer Default: 2000 Description: Maximum delay before reconnection attempt (exponential backoff cap).

Type: integer Default: 2000 Description: Interval for checking request timeouts.


Located in the gcode_viewer section:

{
"gcode_viewer": {
"shading_model": "smooth",
"tube_sides": 4,
"streaming_mode": "auto",
"streaming_threshold_percent": 40,
"layers_per_frame": 0,
"adaptive_layer_target_ms": 16
}
}

Type: string Default: "smooth" Values: "flat", "smooth", "phong" Description: 3D rendering quality:

  • flat - Faceted look, lowest GPU cost
  • smooth - Gouraud shading, good balance (default)
  • phong - Per-pixel lighting, highest quality

Type: integer Default: 4 Values: 4, 8, 16 Description: Cross-section detail for filament paths:

  • 4 - Diamond shape, fastest rendering
  • 8 - Octagonal, balanced quality
  • 16 - Circular, matches OrcaSlicer quality

Type: string Default: "auto" Values: "auto", "on", "off" Description: Large G-code file handling:

  • auto - Stream files that would use too much RAM
  • on - Always stream (lowest memory)
  • off - Always load full file (fastest viewing)

Can be overridden via HELIX_GCODE_STREAMING env var.

Type: integer Default: 40 Range: 1 - 90 Description: Percent of available RAM that triggers streaming mode. Lower values stream smaller files. Only used when streaming_mode is "auto".

Type: integer Default: 0 (auto) Range: 0 - 100 Description: Number of layers to render per frame during progressive 2D visualization:

  • 0 - Auto (adaptive based on render time, default)
  • 1-100 - Fixed value

Higher values = faster caching, but may cause UI stutter on slow devices.

Type: integer Default: 16 Description: Target render time in milliseconds when using adaptive layers_per_frame (only used when layers_per_frame=0). Lower = smoother UI, higher = faster caching. Default 16ms targets ~60 FPS.


Located in the ams section:

{
"ams": {
"spool_style": "3d"
}
}

Type: string Default: "3d" Values: "3d", "flat" Description: Filament spool visualization style:

  • 3d - Bambu-style pseudo-3D canvas with gradients
  • flat - Simple concentric rings

Located under the panel_widgets key, grouped by panel ID. The Home panel uses a multi-page format with explicit grid positions:

{
"panel_widgets": {
"home": {
"pages": [
{
"id": "main",
"widgets": [
{"id": "printer_image", "enabled": true, "col": 0, "row": 0, "colspan": 2, "rowspan": 2},
{"id": "print_status", "enabled": true, "col": 0, "row": 2, "colspan": 2, "rowspan": 2},
{"id": "tips", "enabled": true, "col": 2, "row": 0, "colspan": 4, "rowspan": 2},
{"id": "temperature", "enabled": true, "col": 6, "row": 0, "colspan": 1, "rowspan": 1},
{"id": "fan_stack", "enabled": true, "col": 7, "row": 0, "colspan": 1, "rowspan": 1}
]
},
{
"id": "page_1",
"widgets": [
{"id": "temp_graph", "enabled": true, "col": 0, "row": 0, "colspan": 4, "rowspan": 3},
{"id": "camera", "enabled": true, "col": 4, "row": 0, "colspan": 4, "rowspan": 3}
]
}
],
"main_page_index": 0,
"next_page_id": 2
}
}
}

Migration note: If your config has the older flat-array format (a simple list of widgets without pages) or the legacy home_widgets key, HelixScreen automatically migrates it to the multi-page format on first launch. Your existing widgets are placed on a single page.

Type: object Description: Controls the Home Panel’s pages and widgets. Contains:

  • pages — Array of page objects. Each page has:
    • id — Unique page identifier (e.g., "main", "page_1")
    • widgets — Array of widget objects on this page (see below)
  • main_page_index — Which page is the “main” page (shown on first connect and when double-tapping Home). 0 = first page.
  • next_page_id — Internal counter for generating unique page IDs. Do not modify manually.

Each widget object has:

  • id — Widget identifier (see table below)
  • enabled — Whether the widget is shown (true/false)
  • col — Grid column position (0-based, left to right)
  • row — Grid row position (0-based, top to bottom)
  • colspan — Number of columns the widget spans
  • rowspan — Number of rows the widget spans
  • config — (optional) Per-widget settings object. Currently used by temp_stack and fan_stack for display mode:
    • display_mode"stack" (default) or "carousel". Stack shows compact rows; carousel shows swipeable full-size pages. Toggle via long-press on the widget.

Available widget IDs:

IDWidgetDefaultHardware-Gated
powerMoonraker power device controlsEnabledYes (requires power devices)
networkWiFi/Ethernet statusDisabledNo
firmware_restartKlipper firmware restartDisabledNo
amsMulti-material spool statusEnabledYes (requires AMS/MMU)
temperatureNozzle temperature with heating animationEnabledNo
temp_stackStacked nozzle, bed, and chamber temps (supports carousel mode)DisabledNo
ledLED quick toggleEnabledYes (requires LEDs)
humidityEnclosure humidity sensorEnabledYes (requires sensor)
width_sensorFilament width sensorEnabledYes (requires sensor)
probeZ probe status and offsetEnabledYes (requires probe)
filamentFilament runout detectionEnabledYes (requires sensor)
fan_stackPart, hotend, and auxiliary fan speeds (supports carousel mode with arc dials)EnabledNo
thermistorTemperature sensors (chamber, enclosure, etc.)DisabledYes (requires sensor)
notificationsPending alerts with severity badgeEnabledNo

Notes:

  • Widget grid positions (col, row, colspan, rowspan) determine where each widget appears on its page
  • Hardware-gated widgets are hidden on the Home Panel if their hardware isn’t detected, even when enabled
  • New widgets added in future versions are automatically appended with their default enabled state
  • Unknown widget IDs (from older versions) are silently ignored
  • Up to 8 pages are supported

This is best configured via Edit Mode on the Home Panel (long-press the widget grid) rather than editing the JSON directly. See the Home Panel guide for details on adding pages and arranging widgets.


Located in the cache section:

{
"cache": {
"thumbnail_max_mb": 20,
"disk_critical_mb": 5,
"disk_low_mb": 20
}
}

Type: integer Default: 20 Description: Maximum thumbnail cache size in MB. Cache auto-sizes to 5% of available disk, capped at this limit.

Type: integer Default: 5 Description: Stop caching when available disk falls below this threshold (MB). Prevents filling filesystem.

Type: integer Default: 20 Description: Evict cache aggressively when available disk falls below this threshold (MB). Reduces cache to half normal limit.


Located in the streaming section:

{
"streaming": {
"threshold_mb": 0,
"force_streaming": false
}
}

Type: integer Default: 0 (auto-detect) Description: File size threshold in MB for using streaming (disk-based) operations instead of buffered (in-memory). 0 = auto-detect based on 10% of available RAM.

Can be overridden via HELIX_FORCE_STREAMING=1 env var to force streaming for all files.

Type: boolean Default: false Description: Always use streaming operations regardless of file size. Useful for memory-constrained devices or testing. Can also be set via HELIX_FORCE_STREAMING=1 env var.


Located in the safety section:

{
"safety": {
"estop_require_confirmation": true,
"cancel_escalation_enabled": false,
"cancel_escalation_timeout_seconds": 30
}
}

Type: boolean Default: true Description: Require confirmation dialog before emergency stop. When false, E-Stop triggers immediately. Default is true to prevent accidental emergency stops.

Type: boolean Default: false Description: When enabled, a cancel that doesn’t complete within the configured timeout will automatically escalate to an emergency stop (M112). When false (the default), cancel waits indefinitely for the printer to finish its cancel routine. Leave this off if your printer has a long cancel macro (e.g., toolchangers that need to park tools).

Type: integer Default: 30 Options: 15, 30, 60, 120 Description: How long to wait (in seconds) after sending a cancel before escalating to emergency stop. Only applies when cancel_escalation_enabled is true.


Located in the filament_sensors section:

{
"filament_sensors": {
"master_enabled": true,
"sensors": []
}
}

Type: boolean Default: true Description: Global toggle to enable/disable all filament sensor monitoring. When false, sensor states are ignored and no runout detection occurs.

Type: array Default: [] Description: Array of sensor configurations. Sensors are auto-discovered from Moonraker. Each sensor object has:

  • klipper_name - Full Klipper object name (e.g., "filament_switch_sensor fsensor")
  • role - Sensor role: "none", "runout", "toolhead", "entry"
  • enabled - Boolean to enable/disable individual sensor

Example:

{
"sensors": [
{
"klipper_name": "filament_switch_sensor fsensor",
"role": "runout",
"enabled": true
}
]
}

Located in the plugins section:

{
"plugins": {
"enabled": []
}
}

Type: array Default: [] Description: List of plugin IDs to load. Plugins must be explicitly enabled.

Example:

{
"enabled": ["led-effects", "custom-macros"]
}

Located in the update section:

{
"update": {
"channel": 0,
"dev_url": "",
"r2_url": ""
}
}

Type: integer Default: 0 Values: 0 (Stable), 1 (Beta), 2 (Dev) Description: Update channel selection:

  • 0 - Stable: Tries R2 CDN first ({r2_url}/stable/manifest.json), falls back to GitHub releases API
  • 1 - Beta: Tries R2 CDN first ({r2_url}/beta/manifest.json), falls back to GitHub pre-releases API
  • 2 - Dev: Uses dev_url if set (backward compat), otherwise uses R2 CDN ({r2_url}/dev/manifest.json)

Can also be changed from the Settings panel when beta_features is enabled.

Type: string Default: "" (empty) Example: "https://releases.helixscreen.org/dev" Description: Explicit base URL for the dev update channel. When set and channel is 2, HelixScreen fetches {dev_url}/manifest.json directly, bypassing R2. When empty, the dev channel uses the R2 CDN path ({r2_url}/dev/manifest.json). Must use http:// or https:// scheme. Primarily used for local development servers or self-hosted setups that predate R2 support.

Type: string Default: "" (uses built-in https://releases.helixscreen.org) Example: "https://my-cdn.example.com" Description: Base URL for R2/CDN update manifests. All channels (Stable, Beta, Dev) fetch manifests from {r2_url}/{channel}/manifest.json. When empty, uses the compiled-in default (https://releases.helixscreen.org). Self-hosters can override this to point to their own CDN or R2 bucket. Trailing slashes are automatically stripped.


Located in printer.safety_limits:

{
"printer": {
"safety_limits": {
"max_temperature_celsius": 400.0,
"min_temperature_celsius": 0.0,
"max_fan_speed_percent": 100.0,
"min_fan_speed_percent": 0.0,
"max_feedrate_mm_min": 50000.0,
"min_feedrate_mm_min": 0.0,
"max_relative_distance_mm": 1000.0,
"min_relative_distance_mm": -1000.0,
"max_absolute_position_mm": 1000.0,
"min_absolute_position_mm": 0.0
}
}
}

These override auto-detected limits. Useful for:

  • High-temp printers (increase max_temperature_celsius)
  • Very large printers (increase position limits)
  • Safety restrictions (decrease maximums)

Leave unset (or remove the section) to use Moonraker auto-detection from printer.cfg.


Located in printer.capability_overrides:

{
"printer": {
"capability_overrides": {
"bed_mesh": "auto",
"qgl": "auto",
"z_tilt": "auto",
"nozzle_clean": "auto",
"heat_soak": "auto",
"chamber": "auto"
}
}
}

Values for each setting:

  • "auto" - Use Moonraker detection
  • "enable" - Force feature on
  • "disable" - Force feature off

Use cases:

  • Enable heat_soak when you have a chamber but no chamber heater (soak macro works without)
  • Disable qgl on a printer where it’s defined but not used
  • Enable bed_mesh if detection failed

Delete the config file and restart (use your actual install path):

Terminal window
# Pi with Klipper ecosystem:
rm ~/helixscreen/config/settings.json
# Pi without ecosystem (or if installed to /opt):
sudo rm /opt/helixscreen/config/settings.json
sudo systemctl restart helixscreen

This triggers the first-run wizard.

Edit the config file directly:

Terminal window
nano ~/helixscreen/config/settings.json

Or copy fresh from template:

Terminal window
cp ~/helixscreen/config/settings.json.template ~/helixscreen/config/settings.json

HelixScreen protects your configuration against corruption and data loss:

Configuration writes use atomic file operations — data is written to a temporary file first, then renamed into place. This prevents partial writes from corrupting your config if power is lost during a save.

If settings.json contains invalid JSON (e.g., from manual editing errors), HelixScreen detects the parse failure and:

  1. Renames the corrupt file to settings.json.corrupt (preserved for diagnosis)
  2. Loads safe defaults
  3. Logs the error with details about what went wrong

Every successful config save maintains rolling backups in two locations:

  • /var/lib/helixscreen/settings.json.backup (primary — survives app reinstalls)
  • ~/.helixscreen/settings.json.backup (fallback)

If settings.json is missing at startup (e.g., after a Moonraker update wipe), HelixScreen automatically restores from the most recent backup.

If your config is lost or corrupted:

  1. Automatic: HelixScreen restores from rolling backup on next launch
  2. Manual: Check for settings.json.corrupt in your config directory — this contains your previous (invalid) config that you can manually fix
  3. Fresh start: Copy settings.json.template to settings.json and re-run the setup wizard

Older versions used helixconfig.json. HelixScreen automatically renames this to settings.json on startup — no manual action needed.


HelixScreen accepts command-line options for overriding configuration and debugging.

OptionDescription
-s, --size <size>Screen size: tiny (480×320), small (800×480), medium (1024×600), large (1280×720)
--dpi <n>Display DPI (50-500, default: 160)
--darkUse dark theme
--lightUse light theme
--skip-splashSkip splash screen on startup
--no-soundDisable all sound output (prevents audio backend initialization)
OptionDescription
-p, --panel <panel>Start on specific panel (home, controls, filament, settings, advanced, print-select)
-w, --wizardForce first-run configuration wizard
OptionDescription
--moonraker <url>Override Moonraker URL (e.g., ws://192.168.1.112:7125)
OptionDescription
-v, --verboseIncrease verbosity (-v=info, -vv=debug, -vvv=trace)
--log-dest <dest>Log destination: auto, journal, syslog, file, console
--log-file <path>Log file path (when --log-dest=file)
OptionDescription
--debug-touchesDraw ripple effects at each touch point for diagnosing touch accuracy
--calibrate-touchForce touch calibration on startup
OptionDescription
--screenshot [sec]Take screenshot after delay (default: 2 seconds)
-t, --timeout <sec>Auto-quit after specified seconds (1-3600)
-h, --helpShow help message
-V, --versionShow version information
Terminal window
# Start in dark mode on the settings panel
helix-screen --dark --panel settings
# Override Moonraker connection
helix-screen --moonraker ws://192.168.1.50:7125
# Enable debug logging
helix-screen -vv
# Take screenshot after 5 seconds
helix-screen --screenshot 5

Note: Test mode options (--test, --real-*) are for development only and not documented here.


These can be set in the systemd service file or before running the binary:

Display & Input:

VariableDescription
HELIX_DRM_DEVICEOverride DRM device path (e.g., /dev/dri/card1)
HELIX_DISPLAY_BACKENDOverride display backend (drm, fbdev, sdl)
HELIX_DISPLAY_ROTATIONOverride display rotation in degrees (0, 90, 180, 270)
HELIX_COLOR_SWAP_RBSwap red/blue channels (1 to enable) — fixes inverted colors on some displays
HELIX_TOUCH_DEVICEOverride touch input device (e.g., /dev/input/event1)
HELIX_TOUCH_SWAP_AXESSwap X/Y touch axes (1 to enable)
HELIX_TOUCH_CALIBRATEForce touch calibration on next launch (1 to enable)
HELIX_MOUSE_DEVICEOverride USB mouse device (e.g., /dev/input/event4)
HELIX_KEYBOARD_DEVICEOverride USB keyboard device (e.g., /dev/input/event5)

Theme & Rendering:

VariableDescription
HELIX_THEMEOverride theme (e.g., dracula, nord, gruvbox)
HELIX_GCODE_MODEOverride G-code render mode (3D or 2D)
HELIX_GCODE_STREAMINGOverride G-code streaming mode
HELIX_FORCE_STREAMINGForce streaming for all file operations (1 to enable)
HELIX_HOT_RELOADEnable XML hot reload for development (1 to enable)

Example in service file:

[Service]
Environment="HELIX_DRM_DEVICE=/dev/dri/card1"
Environment="HELIX_TOUCH_DEVICE=/dev/input/event0"

Note: Most users won’t need environment variables. The config file options are preferred. Environment variables are mainly for debugging when the config file isn’t accessible.

For a comprehensive list of all environment variables (including mock/testing, touch calibration, UI automation, and more), see the Environment Variables Reference.


{
"dark_mode": true,
"brightness": 70,
"sounds_enabled": true,
"completion_alert": 2,
"wizard_completed": true,
"wifi_expected": true,
"language": "en",
"log_dest": "journal",
"log_path": "",
"log_level": "warn",
"theme": {
"preset": 0
},
"display": {
"animations_enabled": true,
"time_format": 0,
"rotate": 0,
"sleep_sec": 1800,
"dim_sec": 300,
"dim_brightness": 30,
"drm_device": "",
"gcode_render_mode": 2,
"gcode_3d_enabled": true,
"bed_mesh_render_mode": 0,
"bed_mesh_show_zero_plane": true,
"printer_image": "",
"calibration": {
"valid": false,
"swap_axes": false
}
},
"input": {
"scroll_throw": 25,
"scroll_limit": 10,
"jitter_threshold": 5,
"scroll_guard": false,
"scroll_guard_cooldown_ms": 80,
"touch_device": "",
"force_calibration": false
},
"output": {
"led_on_at_start": false
},
"network": {
"connection_type": "wifi",
"wifi_ssid": "PrinterNetwork",
"eth_ip": ""
},
"printer": {
"name": "Voron 2.4 350",
"type": "Voron 2.4",
"moonraker_host": "localhost",
"moonraker_port": 7125,
"moonraker_api_key": false,
"moonraker_connection_timeout_ms": 10000,
"moonraker_request_timeout_ms": 30000,
"moonraker_keepalive_interval_ms": 10000,
"moonraker_reconnect_min_delay_ms": 200,
"moonraker_reconnect_max_delay_ms": 2000,
"moonraker_timeout_check_interval_ms": 2000,
"heaters": {
"hotend": "extruder",
"bed": "heater_bed"
},
"temp_sensors": {
"hotend": "extruder",
"bed": "heater_bed"
},
"fans": {
"part": "fan",
"hotend": "heater_fan hotend_fan",
"chamber": "",
"exhaust": ""
},
"leds": {
"strip": "",
"selected_strips": ["neopixel caselight"],
"led_on_at_start": false,
"last_color": 16777215,
"last_brightness": 100,
"color_presets": [16777215, 16711680, 65280, 255, 16776960, 16711935, 65535],
"auto_state": {
"enabled": false,
"mappings": {
"idle": { "action": "brightness", "brightness": 50, "color": 0 },
"heating": { "action": "color", "color": 16711680, "brightness": 100 },
"printing": { "action": "brightness", "brightness": 100, "color": 0 },
"paused": { "action": "off" },
"error": { "action": "color", "color": 16711680, "brightness": 100 },
"complete": { "action": "color", "color": 65280, "brightness": 100 }
}
},
"macro_devices": []
},
"extra_sensors": {},
"hardware": {
"optional": [],
"expected": [],
"last_snapshot": {}
},
"default_macros": {
"cooldown": "SET_HEATER_TEMPERATURE HEATER=extruder TARGET=0\nSET_HEATER_TEMPERATURE HEATER=heater_bed TARGET=0",
"load_filament": { "label": "Load", "gcode": "LOAD_FILAMENT" },
"unload_filament": { "label": "Unload", "gcode": "UNLOAD_FILAMENT" },
"macro_1": { "label": "Clean Nozzle", "gcode": "HELIX_CLEAN_NOZZLE" },
"macro_2": { "label": "Bed Level", "gcode": "HELIX_BED_LEVEL_IF_NEEDED" }
},
"safety_limits": {
"max_temperature_celsius": 400.0,
"min_temperature_celsius": 0.0,
"max_fan_speed_percent": 100.0,
"min_fan_speed_percent": 0.0,
"max_feedrate_mm_min": 50000.0,
"min_feedrate_mm_min": 0.0,
"max_relative_distance_mm": 1000.0,
"min_relative_distance_mm": -1000.0,
"max_absolute_position_mm": 1000.0,
"min_absolute_position_mm": 0.0
},
"capability_overrides": {
"bed_mesh": "auto",
"qgl": "auto",
"z_tilt": "auto",
"nozzle_clean": "auto",
"heat_soak": "auto",
"chamber": "auto"
}
},
"gcode_viewer": {
"shading_model": "smooth",
"tube_sides": 8,
"streaming_mode": "auto",
"streaming_threshold_percent": 40,
"layers_per_frame": 0,
"adaptive_layer_target_ms": 16
},
"panel_widgets": {
"home": [
{"id": "temperature", "enabled": true},
{"id": "network", "enabled": true},
{"id": "led", "enabled": true},
{"id": "ams", "enabled": true},
{"id": "notifications", "enabled": true},
{"id": "power", "enabled": true},
{"id": "firmware_restart", "enabled": false},
{"id": "humidity", "enabled": false},
{"id": "width_sensor", "enabled": false},
{"id": "probe", "enabled": false},
{"id": "filament", "enabled": false},
{"id": "temp_stack", "enabled": false},
{"id": "fan_stack", "enabled": true},
{"id": "thermistor", "enabled": false}
]
},
"ams": {
"spool_style": "3d"
},
"cache": {
"thumbnail_max_mb": 20,
"disk_critical_mb": 5,
"disk_low_mb": 20
},
"streaming": {
"threshold_mb": 0,
"force_streaming": false
},
"safety": {
"estop_require_confirmation": true
},
"filament_sensors": {
"master_enabled": true,
"sensors": []
},
"plugins": {
"enabled": []
},
"update": {
"channel": 0,
"dev_url": ""
}
}

Back to: User Guide | Troubleshooting