Lua for the User & Migration
此内容尚不支持你的语言。
This document explains the Lua-based Hyprland stack introduced by the Lua migration. It is written for existing HyDE users deciding whether, and how, to move from the legacy Hyprlang configuration.
At a glance 👁️🗨️
Section titled “At a glance 👁️🗨️”HyDE is not replacing every configuration format with Lua. Nor are we forcing a refactor of every script and component.
It is mostly about longevity, sealing down the Hyprland runtime from a Hyprlang .conf tree into something stable.
Also, the addition of Lua modules and retaining TOML for declarative HyDE settings and dotfile manifests are natural fits.
Essentially, we’re migrating to something with better support, Lua. Quite the popular scripting and systems language, among other tasks it creates variables like hl, start, hyde, hs etc. This is a core upgrade:
Hyprlang was the old material we used to carry important environment variables and its functionality was limited. Here’s an example taken from the old startup.conf:
exec-once = dbus-update-activation-environment --systemd --all #? Might fail so we hardcode the variables belowexec-once = $start.DBUS_SHARE_PICKER # dbus-update-activation-environment (one-time setup)exec-once = $start.SYSTEMD_SHARE_PICKER # systemctl --user import-environment (one-time setup)exec-once = $start.XDG_PORTAL_RESET # resetxdgportal.sh (one-time setup)As you can see the infrastructure was always somewhat unbalanced about the long-term viability. Simply put, Hyprlang was good for having a table of variables, not for moving parts like is required for runtime operations.
hl.on( "hyprland.start", function() check_exec(hs.dbus_share_picker) check_exec(hs.systemd_share_picker) check_exec(hs.auth_dialogue) )Instead of hoping that startup.conf goes off before hyprland starts, we declare an event hyprland.start or hyde.activate which chains into runtime operation, hyde-shell reload shows this off as it rebuilds core environments.
Layouts
Section titled “Layouts”Layouts is a new and exclusive lua feature that allows the user to change the behaviour of their whole WM in 1 swift action, keybinds, transitions inbetween workplaces, and windows among just the general feel of your computer. The default workflow and layout settings are unset, meaning that something else has to launch them.
Choose a layout:
hyde-shell layouts --selectNotable files & concerns
Section titled “Notable files & concerns”| Concern | Legacy setup | Lua setup |
|---|---|---|
| Hyprland entrypoint | ~/.config/hypr/hyprland.conf or $XDG_DATA_HOME/hyprland.conf | $XDG_DATA_HOME/hypr/hyde.lua and ~/.config/hypr/hyprland.lua |
| Window rules | ~/.config/hypr/windowrules.conf | /.local/share/hypr/lua/window_rules.lua but preferably you’d port them into hyprland.lua |
| Startup settings | [hyprland-start] in config.toml | [desktop.start] in $XDG_DATA_HOME/hyde/config-registry.toml |
| UserPrefs | .config/hypr/userprefs.conf | ~/.local/share/hypr/lua/defaults.lua |
| backup-restore | legacy restore lists | deez manifests invoked by install.sh -r |
Lua prevents a lot of the one-off tricks we started to rely on in order to make hyprlang work for finer routines, but it is not a guaranteed performance upgrade. Its main benefit is a more maintainable configuration and long-term support. The following table takes into account ‘changes’ as the differences between the latest available dev branch and a ‘stable’ release from before May 12th 2026 [95adf01]:
| Files changed | | LOC changes | Scripts | Description | | --- | --- | --- | --- | | 44 | +2,074, −159 | 33 added, 11 modified, 29 unchanged | Adds dotfile manifests and migrations; updates installation and restore support. |
the new dots and dots-groups folders in ~/HyDE/Scripts/ containing the dot-file schemas.
Helper functions for install.sh which are supposed to make migrating more simple and reinforces the python env
~/HyDE/Scripts/dots/hyprland.toml deploys the Lua tree.
All previous entrypoints have been updated;
| Entrypoint | Description |
|---|---|
| $XDG_DATA_HOME/.local/share/hypr/hyde.lua | Rewards promises to the environment such as the runtime environment, core lua scripts, all .config/ userprefs and .local/ fallbacks |
| $XDG_CONFIG_HOME/hypr/hyprland.lua | User override layer or simply ‘user preferences’ is part of the desired zone for interfacing with this upgrade, from adding keybinds to summoning HyDE scripts with lua. The require("")directive is helpful |
Runtime upgrades
Section titled “Runtime upgrades”Since lua is now parrallel in terms to our python environment. HyDE activates the Lua stack through UWSM:
UWSM environment scripts -> ~/.local/lib/hyde/shell/activate -> HYDE_MODE=lua and HYPRLAND_CONFIG=.../hypr/hyde.lua -> Hyprland loads hyde.lua -> HyDE loads its Lua modules and ~/.config/hypr/hyprland.luaThe shared runtime belongs under $XDG_DATA_HOME/hypr/; your user changes belong under $XDG_CONFIG_HOME/hypr/. This follows HyDE’s usual separation between maintained data and user-owned configuration. See Secrets & Portals for the related UWSM and XDG session model.
Hyprlang to Lua
Section titled “Hyprlang to Lua”Hyprlang files are declarative: they describe settings and dispatch commands. What’s inside a .conf file was a lie, it was and will always tend to be Hypr compliant syntax. Lua can express the same settings, then add functions, event handlers, and shared helpers where they make sense; which some conf files were doing anyway.
For example, a legacy input block such as:
input { kb_layout = us,es accel_profile = flat}becomes a more meaningful profile:
hl.config({ input = { kb_layout = "us,es", accel_profile = "flat", },})Likewise, a key binding can use HyDE’s Lua helpers instead of a comma-delimited bind line:
hl.bind( "SUPER + Q", hl.dsp.window.close(), { description = "[Window Management] close focused window" })#~/.config/hypr/hyprland Conf -> Lua guideMOD=hyde.config.modifiers.main_F = {description = "[Launcher|Apps] Demuestra layouts"}hl.bind(MOD .. " + ALT + L", hl.dsp.exec_cmd("hyde-shell layouts --select"), _F)Start with HyDE’s shipped modules for patterns that match the installed runtime, you could even restore the previous keybinds to your liking and mess about with the start_up as we’ll see next up.
TOML still has a role
Section titled “TOML still has a role”TOML remains the data layer between scripting and runtime calls. $XDG_DATA_HOME/hyde/config-registry.toml contains portable HyDE preferences such as desktop applications, startup commands and helpful aliases, while the installed schema describes valid fields. HyDE’s configuration registry also uses TOML to describe editable files and their hooks, including ~/.config/hypr/hyprland.lua.
The separation:
- Use TOML for HyDE options and schema-backed data.
- Use Lua for Hyprland settings, bindings, rules, layouts, and event-driven behaviour.
- Leave HyDE-managed files in
$XDG_DATA_HOMEalone unless you are developing HyDE itself.
What must be ported manually
Section titled “What must be ported manually”At minimum:
keybindings.confwindowrules.confmonitors.confuserprefs.conf
The Lua manifest intentionally conflicts with the legacy Hyprland manifest. Old files may remain on disk after a restore, but they are no longer the configuration source. Keep a backup until you have checked every bind, monitor, rule, and startup service in a new session.
Layouts and startup
Section titled “Layouts and startup”Use hyde-shell layouts --select to choose a shipped or custom layout.
~/.config/hypr/lua/layouts/custom.luaThe old [hyprland-start] section has been replaced by [desktop.start] in $XDG_DATA_HOME/hyde/schema/config.toml. Lua’s start_up.lua runs these events in accordance to the local schema, when Hyprland emits its start event. The schema installed with HyDE documents the supported keys.
Restore and deez
Section titled “Restore and deez”deez is HyDE’s dotfile deployment backend in the Lua migration. It is normally an implementation detail: ./install.sh -r uses the private executable in HyDE’s Python environment to deploy the adequate manifests. Honestly, very litle manual intervention is needed in order to use the new dotfile client.
If restore reports that deez-dots is missing, make sure your local ~/HyDE folder is up-to-date, then
prepare the environment quickly:
cd /path/to/HyDE/Scripts./install.sh -p./install.sh -rFor an intentionally controlled retry, use the same command shape as the installer, not an older dot subcommand:
"$HOME/.local/state/hyde/python_env/bin/deez" \ --source /path/to/HyDE \ --config /path/to/HyDE/Scripts/dots-groups/core.toml \ dots --skip-git --listReplace the --list flag for --deploy all only if you’re sure it won’t cause conflicts
If it does, please don’t report on it. As mentioned deez-dots is an implementation detail,
it’s very practical outside our context but within, has been harnessed down so that there’s very little
risk of it failing outside user error.
- Old Hyprlang files and their Lua replacements
#This is the practical migration map, useful if you want to clean-up a migration: -- ~/.config/hypr/hyprland.conf -> ~/.local/share/hypr/hyde.lua:1 -- ~/.config/hypr/keybindings.conf -> ~/.local/share/hypr/lua/key_binds.lua:1 -- ~/.config/hypr/userprefs.conf -> ~/.config/hypr/hyprland.lua:17 -- ~/.config/hypr/windowrules.conf, monitors.conf, nvidia.conf -> user hyprland.lua or a Lua module under lua/ -- ~/.config/hypr/animations.conf, workflows.conf -> Lua workflow/animation selectors, not the old conf files -- ~/.local/share/hypr/_.conf and ~/.local/share/hyde/_.conf files -> mostly retired leftovers, kept only for migration/backups, the schema folder is useful to backup only if you have edited relevant startup instructions.Migration checklist
Section titled “Migration checklist”- Review Installation and clone the Lua-enabled HyDE revision you intend to use.
- Make a smart backup. I recommend:
~/.config/hypr,~/.config/hyde,~/.config/dconf,~/.config/gtk-3.0,~/.config/qt5ct,~/.config/qt6ct,~/.config/kdeglobals,~/.gtkrc-2.0, and~/.config/uwsm. - Definitely make sure
luarocksand the preface is set-up:./install.sh -p. Running./install.sh -rwill not and can not translate or transfer your existing .conf syntax into usable HyDE+Lua syntax. - Port legacy Hyprlang customisations into the directories described throughout this doc. ($XDG_DATA_HOME, $HYPRLAND_CONFIG, $UWSM_FINALIZE_VARNAMES)
- Start a new HyDE session(should happen automatically), then verify the runtime and reload Hyprland:
sh -c 'printf "%-18s %s\n" "HYDE_MODE" "${HYDE_MODE:-<unset>}"printf "%-18s %s\n" "HYPRLAND_CONFIG" "${HYPRLAND_CONFIG:-<unset>}"printf "%-18s %s\n" "DCONF_PROFILE" "${DCONF_PROFILE:-<unset>}"printf "%-18s %s\n" "HYDE_ACTIVATED" "${HYDE_ACTIVATED:-<unset>}"printf "%-18s %s\n" "HYDE_FEATURE_LUA" "${HYDE_FEATURE_LUA:-<unset>}"printf "%-18s %s\n" "QT_QPA_PLATFORM" "${QT_QPA_PLATFORM:-<unset>}"echoneed_p=0if command -v luarocks >/dev/null 2>&1; then echo "luarocks: "else echo "luarocks: not found" need_p=1fiif [ -x "$HOME/.local/state/hyde/python_env/bin/deez" ]; then echo "deez (python env): found"else echo "deez (python env): not found" need_p=1fiif [ -n "$HYPRLAND_CONFIG" ] && [ -f "$HYPRLAND_CONFIG" ]; then echo "HYPRLAND_CONFIG: "else echo "HYPRLAND_CONFIG: unset!" exit 1fiif [ -n "$DCONF_PROFILE" ] && [ ! -f "$DCONF_PROFILE" ]; then echo "warn: DCONF_PROFILE is set but the file itself is missing."fiechoif [ "$need_p" -eq 1 ]; then echo "=> run ./install.sh -p before ./install.sh -r"else echo "=> ./install.sh -p ran, safe to skip straight to -r"fi'