Skip to content

config

Read-only, typed configuration access. Host-injected capability — the script reads config values without knowing where they come from. The config file is declared explicitly in star.mod; there is no on-disk guessing. On PC the CLI reads that file before the script runs; on ESP32 the file is provisioned to the device over deploy.

Version v0.1
Platform PC, ESP32
Type Native (C)

star.mod

require dev-libs/config v0.1

config config.json

The config directive names the file to load (relative to star.mod, or an absolute path). The programmer must declare it — if config is imported but no file is declared, the CLI warns and every getter returns its fallback. You can point at any file, e.g. config prod.json. See the star.mod reference for the full directive description.

Usage

import "config"

The config file

myproject/
  star.mod         <-- declares: config config.json
  config.json      <-- loaded by the host before the script runs
  main.star
{
    "server": {
        "host": "192.168.1.10",
        "port": 8080,
        "debug": true
    },
    "wifi": {
        "ssid": "StarNet",
        "password": "secret123"
    }
}

Functions

Typed Getters

Function Signature Description
config.getString(key, fallback) (string, string) -> string Get string value or fallback
config.getNumber(key, fallback) (string, number) -> number Get number value or fallback
config.getBool(key, fallback) (string, bool) -> bool Get bool value or fallback
var host: string = config.getString("server.host", "127.0.0.1")
var port: number = config.getNumber("server.port", 8080)
var debug: bool = config.getBool("server.debug", false)

Fallback is returned when:

  • Key does not exist
  • Key exists but is a different type

Lookup

Function Signature Description
config.has(key) (string) -> bool Check if key exists
config.keys(prefix) (string) -> array List keys under a section
if (config.has("mqtt.broker")) {
    # mqtt configured
}

var sections: array = config.keys("")      # top-level keys
var wifi_keys: array = config.keys("wifi") # ["ssid", "password"]

Dotted Key Paths

Keys use dot notation to traverse nested objects:

config.getString("server.host", "")    # root -> server -> host
config.getNumber("mqtt.port", 1883)    # root -> mqtt -> port
config.getString("app_name", "")       # root -> app_name

Pattern: IoT Device Config

{
    "device": {
        "id": "sensor-01",
        "interval_ms": 5000
    },
    "mqtt": {
        "broker": "mqtt.stardyn.com",
        "port": 1883,
        "topic": "sensors/temp"
    },
    "wifi": {
        "ssid": "IoTNet",
        "password": "secret"
    }
}
package main

import "config"
import "http"
import "json"

fn main():void {
    var id: string = config.getString("device.id", "unknown")
    var interval: number = config.getNumber("device.interval_ms", 10000)
    var broker: string = config.getString("mqtt.broker", "localhost")

    console.log(id)
    console.log(interval)
    console.log(broker)
}

Design Philosophy

Config is a read-only, host-injected capability. The host loads the configuration before the script runs; StarLang code has no filesystem API. The script reads values but never writes them, and never knows where they came from.

  • Config = deployment-time values injected by the host (immutable at runtime)
  • Settings = user/runtime-writable persistent data (planned as separate settings module)

On PC, the host (CLI) reads the file declared by config <file> in star.mod. On ESP32, deploy provisions that same file to the device over the serial link (an SLD SET-CONFIG frame) before running the image; it stays resident across runs. The script just calls typed getters with fallbacks — same code, both platforms.

Notes

  • Config is loaded once at startup by the host, not by script code — StarLang has no filesystem API
  • The file is declared explicitly via config <file> in star.mod (relative to star.mod, or absolute)
  • On PC, the CLI loads the declared file before running
  • On ESP32, deploy provisions the declared file to the device (SLD SET-CONFIG); it persists across runs
  • JSON is parsed with cJSON (same as the json module)
  • Maximum config file size: 1MB
  • Dotted paths traverse nested objects: "a.b.c" resolves root["a"]["b"]["c"]
  • Type-safe: getNumber on a string key returns the fallback, never crashes
  • keys("") returns top-level keys, keys("section") returns that section's keys