> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ryoku.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Customize

> Edit the plain config files updates never touch — personal Hyprland overrides, hand-pinned displays, and per-app settings.

Most customization happens in **Ryoku Settings** (the Hub), opened with `Mod+,`.
This page is the other half: the plain files Ryoku reserves for you in
`~/.config/`, which `ryoku update` never touches. Reach for them when the GUI
does not cover what you want, or when you would rather edit text than click.

<CardGroup cols={2}>
  <Card title="Settings (the GUI)" icon="sliders" href="/docs/settings">
    Appearance, displays, input, keybinds, the shell, and more, applied live.
  </Card>

  <Card title="Theming" icon="palette" href="/docs/theming">
    Full-system themes, the wallust palette, and wallpapers.
  </Card>
</CardGroup>

<Info>
  Displays have both paths: tune them in **Settings > Displays** (see [Displays &
  hardware](/docs/hardware)), and hand-pin the stubborn ones in
  `monitors_user.lua`, below.
</Info>

## Personal Hyprland overrides: `user.lua`

`~/.config/hypr/user.lua` is yours. It is never shipped and never touched by
`ryoku materialize`, and it loads **last** in the Hyprland config, so it wins
over both the shipped defaults and anything Ryoku Settings writes.

The load order, from `ryoku/hyprland/hyprland.lua`, is:

1. `modules.env`, `keyboard.lua`.
2. Generated drop-ins `gpu.lua` and `monitors.lua` (and your `monitors_user.lua`
   if present).
3. The base modules (`displays`, `input`, `decoration`, `animations`, `binds`,
   `resize`, `ryoshot`, `window_rules`, `fullscreen`, `autostart`).
4. The active `theme` (selected in Settings).
5. `settings.lua` (written by the Hub).
6. `user.lua` (yours, loaded last, wins).

```lua theme={"dark"}
-- ~/.config/hypr/user.lua
-- Personal overrides; this file is never overwritten by ryoku update.

-- An extra keybind.
hl.bind("SUPER", "U", "exec, kitty -e htop")

-- Force a different window rule.
hl.windowrule("float", "class:^(pavucontrol)$")
```

<Tip>
  Use the `hl` API the modules use (`hl.bind`, `hl.windowrule`, the keyword
  setters); do not shell out to `hyprctl` from Lua when an `hl` call exists.
</Tip>

## Manual monitor pinning: `monitors_user.lua`

For everyday display changes, use **Settings > Displays** (see [Displays &
hardware](/docs/hardware)). It writes the generated `~/.config/hypr/monitors.lua`,
which `ryoku-monitor` also rewrites once per machine and on hotplug or GPU reset.

When you need a layout the panel cannot express, a fake-EDID display that needs a
forced mode, a forced modeline, or a specific position, write
`~/.config/hypr/monitors_user.lua` instead. It loads after the generated file, so
your pins win, and updates never touch it. A template ships at
`~/.config/hypr/monitors_user.lua.example`.

## Per-app settings

Each app under `ryoku/apps/<app>/` keeps its native format under its own
directory; there is no Lua wrapper for a tool that reads its own config. Where an
app ships a base file, drop your changes in the paired override file so an update
cannot clobber them:

| App       | Shipped file                 | Override file                |
| --------- | ---------------------------- | ---------------------------- |
| Kitty     | `~/.config/kitty/kitty.conf` | `~/.config/kitty/user.conf`  |
| Fish      | `~/.config/fish/config.fish` | `~/.config/fish/user.fish`   |
| Starship  | `~/.config/starship.toml`    | edit in place                |
| Neovim    | `~/.config/nvim/`            | LazyVim's own override paths |
| Yazi      | `~/.config/yazi/yazi.toml`   | edit in place                |
| Fastfetch | `~/.config/fastfetch/`       | edit in place                |

## What survives an update

[`ryoku materialize`](/docs/cli#config-lay-down-ryoku-materialize) clobbers the
files Ryoku ships and prunes files a past release shipped but this one dropped. It
**never touches** files Ryoku never shipped, which is what makes `user.lua`,
`monitors_user.lua`, `kitty/user.conf`, `fish/user.fish`, and your own additions
survive every update.

The generated drop-ins (`hypr/monitors.lua`, `hypr/gpu.lua`) are seeded only when
absent and are never clobbered or pruned, so an update never resets your display
layout or GPU pin.

<Warning>
  Editing a shipped file in place (anything in the "shipped file" column above,
  or `hypr/hypridle.conf`, and the other base configs) is reset on the next
  `ryoku materialize`. Put lasting changes in an override file, or in `user.lua`.
</Warning>

## Reloading after a change

After editing a file by hand:

```bash theme={"dark"}
ryoku reload
```

This restarts the shell and reloads Hyprland. Ryoku Settings applies its own
changes live and does not need a reload.

## See also

<CardGroup cols={2}>
  <Card title="Settings" icon="sliders" href="/docs/settings">
    The GUI for everything above, and the panels this page complements.
  </Card>

  <Card title="Theming" icon="palette" href="/docs/theming">
    Themes, palette, and wallpapers.
  </Card>

  <Card title="Displays & hardware" icon="display" href="/docs/hardware">
    The GUI display, GPU, input, and power controls.
  </Card>

  <Card title="Keybindings" icon="keyboard" href="/docs/keybindings">
    The shipped binds `user.lua` can override.
  </Card>
</CardGroup>
