HN Debrief

Hyprland 0.55 announced the switch to Lua for its config files

  • Programming
  • Developer Tools
  • Open Source
  • Linux

Hyprland 0.55 replaced its custom config language with Lua, which means users can now write callbacks, conditionals, and other real program logic directly in window manager config. That landed as a familiar fork in the road for developer tools. Either keep config dead simple and declarative, or admit the product is programmable and give users a real language. Most of the energy went into attacking the mushy middle, where projects start with a plain format, bolt on variables and templating, then slowly reinvent a bad scripting language anyway.

If your product’s config is growing variables, templating, and event hooks, decide early whether that logic belongs in a real embedded language or in a narrow plugin boundary. Half-built DSLs usually end up with the worst properties of both.

Discussion mood

Mixed but pragmatic. Many people think Lua is a sensible move for a power-user window manager because users already want event-driven and machine-specific logic, but there is also real fatigue with config churn, upgrade breakage, and the way code-as-config turns into a maintenance burden.

Key insights

  1. 01

    Config systems move in cycles

    Configuration formats rarely stay where they start. They grow overrides, templating, and escape hatches until they effectively become a language, then projects reset back toward a simpler surface. Examples in the comments pushed this beyond Hyprland, from Python packaging to Helm and WirePlumber, which makes the Lua switch look like a normal phase in a longer product lifecycle rather than a one-off design whim.

    Treat config design as something that will evolve under user pressure. If you are adding the third or fourth escape hatch, stop and decide whether to formalize programmability or cut scope back before the surface area becomes unmaintainable.

      Attribution:
    • rdtsc #1 #2
    • ossopite #1
    • zetanor #1
    • serf #1
  2. 02

    Window managers are unusually hard to keep declarative

    A compositor is not just static preferences. Users want hooks that fire on keypresses, changing window titles, scratchpad behavior, and layout reactions to runtime state. The comments made the key point that many window managers are already Turing complete in practice because they execute shell commands or expose IPC, so embedding Lua mainly moves that logic closer to the product and avoids awkward external glue.

    For event-driven software, compare embedded scripting against the real alternative, which is usually shell snippets and sidecar processes, not a clean declarative world. The better design is the one that keeps complex behavior observable and testable.

      Attribution:
    • hombre_fatal #1
    • mort96 #1
    • crest #1
    • honeycrispy #1
    • phire #1
  3. 03

    There is a real middle ground

    Several comments pushed back on the idea that the only choices are dumb text files or a full programming language. CUE, Dhall, Jsonnet, and Starlark were cited as examples of config languages that support abstraction and validation without becoming unrestricted runtime code. That matters because it reframes the tradeoff. Hyprland chose Lua, but other products with more analyzable config needs could get reuse, schema checking, and composition without taking on full script semantics.

    If your config needs generation, validation, and composition more than event callbacks, evaluate purpose-built languages before embedding Python or Lua. They can preserve tooling and predictability that full scripting tends to lose.

      Attribution:
    • ianburrell #1
    • ciupicri #1
    • AlotOfReading #1
    • HiPhish #1
  4. 04

    Small extension surfaces age better

    The most durable alternative in the comments was not pure declarative config by itself. It was declarative config plus a narrow extension boundary like include files, a companion daemon, IPC, or a plugin API. The point is not purity. It is blast-radius control. When upgrades happen, a small and stable interface breaks less often than a config language wired deeply into application internals.

    If you expect long-lived user customizations, invest in a minimal extension API and keep most behavior outside the core config parser. That gives power users room without forcing every upgrade to preserve language-level behavior.

      Attribution:
    • vbernat #1
    • nickjj #1
    • skydhash #1
    • tombert #1
  5. 05

    Project velocity matters as much as language choice

    Comments about Hyprland’s churn were more revealing than the Lua debate itself. One complaint focused on fast-moving forks and dependency breakage across the broader stack. Another said simple hand-written configs remain stable and most pain comes from copying giant community setups. Together they point to the real operational issue. Programmable config is tolerable when the surrounding platform is stable and conventions are tight. It is painful when the product and ecosystem both move fast.

    When evaluating a customizable tool, judge the maintainer’s stability posture and ecosystem discipline, not just the syntax. A boring config language on a chaotic platform can be worse than Lua on a stable one.

      Attribution:
    • colinsane #1
    • m4xp #1
    • gchamonlive #1
    • 0x20cowboy #1

Against the grain

  1. 01

    Established document formats can be enough

    The niri example argued that a readable document-style config like KDL can cover real-world window manager needs without variables, loops, or callbacks, and that the comfort comes from staying close to documented syntax instead of drifting into user-invented patterns. A reply challenged whether KDL is truly established, but that does not undercut the broader point that some users value legibility and explicit includes more than open-ended power.

    Do not assume advanced users automatically want scripting. For many products, a well-scoped config format with composition features and solid docs will satisfy more people than an embedded language.

      Attribution:
    • nickjj #1
    • WhyNotHugo #1
  2. 02

    Recompile-as-config still has fans

    The dwm approach flips the whole debate by making customization literal source edits. That sounds absurdly heavyweight to most users, but the defense was that one simple codebase can be easier to understand than a maze of ad hoc config files and hidden merge rules. It also encourages users to learn the software’s internals instead of treating configuration as a separate magic layer.

    For small, fast, developer-facing tools, direct source customization is a viable product choice if you optimize for transparency over accessibility. It will shrink your audience, but it can also eliminate an entire class of config design problems.

      Attribution:
    • leephillips #1 #2
    • drdexebtjl #1

In plain english

CUE
CUE is a data validation and configuration language designed to combine values, schemas, and constraints.
Dhall
A programmable configuration language designed to stay strongly typed and predictable.
Gradle
A build automation system for software projects that uses Groovy or Kotlin for build configuration.
Helm
A package manager for Kubernetes that uses templates to generate deployment configuration files.
Hyprland
A Wayland compositor and tiling window manager for Linux focused on customization and dynamic layouts.
i3
A popular tiling window manager for X11 on Linux that uses a simple text configuration format.
IPC
Inter-process communication, the mechanisms programs use to send messages or commands to each other.
Jsonnet
A data templating language for generating JSON and related configuration formats with functions and imports.
KDL
KDL stands for KDL Document Language, a structured document and configuration format with a node-based syntax.
Lua
A small embeddable programming language often used for scripting and application configuration.
Nix
A package manager and configuration system built around a functional language for reproducible environments.
Starlark
A deterministic scripting language derived from Python and commonly used for build and configuration systems like Bazel.
Sway
A tiling Wayland window manager with a more declarative configuration style than Hyprland.
Turing complete
Able to express arbitrary computation, meaning a language can in principle implement any program given enough time and memory.
WirePlumber
A session and policy manager for PipeWire on Linux that controls audio and video device behavior.
YAML
A human-readable data serialization format widely used for configuration files.

Reference links

Config complexity and design references

  • Configuration complexity clock
    Referenced as a named version of the cycle where simple config grows into a language and eventually resets.
  • Greenspun's tenth rule
    Cited to explain why projects that resist real scripting often end up reinventing half a programming language.
  • Lua history
    Used to support the point that Lua was originally created for configuration and embedding use cases.

Alternative config formats and tools

  • CUE language
    Named as a strong modern configuration language with schema and validation support.
  • scfg
    Mentioned as a simple config format already used in this ecosystem as an alternative to KDL-style config.
  • Roto documentation
    Suggested as a more modern embeddable language than Lua, with static typing and Rust-like syntax.

Hyprland migration and related configs

Window manager and ecosystem examples

  • persway
    Linked as an example of external glue needed to get more advanced Sway behavior.
  • i3 companion daemon write-up
    Shared to illustrate the sidecar-daemon model for adding dynamic behavior to a simpler window manager config.
  • dwm customization
    Linked to defend the source-edit-and-recompile approach to customization.