Minimal aesthetic arch linux + hyprland dotfiles
README
hyprsimple
Minimalist and aesthetically pleasing Hyprland dotfiles for Arch Linux. Just the essential utilities for everyday use, with a clean and beautiful look and feel. Nothing fancy.
If you want more features, Hyprsimple supports a plugin system, so you can install any plugin you like or build your own. Read PLUGINS.md to learn more.
If you encounter any issues or have feedback, feel free to open an issue.
[!Note] Muslimtify is installed by default as an external plugin.
hyprsimple-plugin remove muslimtifyremoves its integration and daemon and keeps the package and your settings.hyprsimple-plugin install https://github.com/muslimtify-org/muslimtify-hyprsimple.gitinstalls or enables it again.
Demo
https://github.com/user-attachments/assets/f43671d7-4cd2-4cef-a13d-b3c28e432ccd
Features
- Switch between 40 themes with one key, and every app follows at once: the bar with its menus and notifications, ghostty, hyprlock and btop. The well known colorschemes are here, Dracula, Solarized, Catppuccin, Tokyo Night, Rosé Pine, Gruvbox, Nord, Everforest, Kanagawa, Ayu, Nightfox, Oxocarbon and more, in dark and light.
- Pick themes and wallpapers visually, from a carousel of previews in a panel of the bar, with each theme's colour swatches, filterable by typing.
- Every theme has its own wallpapers, with a picker and a cycle switch.
- The installer detects your hardware: NVIDIA, hybrid GPU power saving, Vulkan, Intel iGPU, WiFi and battery.
- The session is Wayland-native through uwsm, with no X11 dependencies.
- An optional "Hyprsimple" entry on the login screen, so hyprsimple can sit beside another Hyprland setup on the same machine.
- The Hyprland config is split into focused files.
- GTK and Qt follow the theme, including light or dark mode.
- On a laptop, a low battery dims the screen and switches to power saver, and the charger puts both back.
- The system panel switches the power mode between power saver, balanced and performance through power-profiles-daemon.
- Screen recording with the microphone, system audio, or no sound.
- Screenshots of a monitor, a window, a region, or straight to the clipboard.
- Clipboard history in a panel of the bar, with search, pictures shown as pictures, and removal of one entry or all of them.
- A nightlight toggle for a warm screen temperature.
- Audio output switching with one key.
- An app launcher in a sidebar that grows from the left edge. It searches names, keywords and initials, and lists the apps you start most first.
- A Quickshell bar with panels for the calendar, system usage, volume, microphone, network, bluetooth and power.
- Prayer times on the bar through muslimtify, with every setting in its panel.
- A firewall (UFW) configured out of the box.
- In-place updates through
hyprsimple-update, which never overwrites your~/.config. - Migrations deliver fixes to machines already installed, once each and safe to repeat.
- One-command diagnostics with
hyprsimple-debugfor issue reports.
Install
git clone https://github.com/rizukirr/hyprsimple.git
cd hyprsimple
./install.sh
The install asks for your sudo password once, at the start, and then runs to the end without stopping. Package operations confirm nothing, so you can start it and walk away. It comes back to you once, at the very end, to ask whether to log out.
If you would rather read what pacman is about to do, ./install.sh --interactive puts every confirmation back, including the full system upgrade. It also asks which AUR helper to install when you have neither paru nor yay, instead of taking paru. The helper comes from a repository when your distribution ships one, and is built from the AUR otherwise. Whichever helper you already have is the one used either way, and HYPRSIMPLE_AUR_HELPER=yay ./install.sh settles a machine that has both.
./install.sh --session-entry also adds a "Hyprsimple" entry to the login screen. It starts the same config as the stock Hyprland entry, so it changes the name you pick and nothing else. hyprsimple-session.sh adds or removes it on an existing install, and the FAQ says what it does and does not separate.
[!WARNING] These dotfiles are tested on a fresh Arch Linux install where Hyprland was selected as the desktop during installation. The login entry has also been tested beside another Hyprland setup on the same machine, and the FAQ lists what the two still share. Coming from another desktop environment (KDE, GNOME and the like) is untested and may need manual cleanup.
If you run into a problem installing hyprsimple, please open an issue. Run hyprsimple-debug first and attach the link it gives you. It bundles your hardware, journal warnings, migration state and the install log (~/.local/state/hyprsimple/install.log) into a single paste that expires in 24 hours. Review it before uploading, because it includes your hostname and package list.
Update
[!IMPORTANT] If you installed hyprsimple before it could update itself, run this once to get on the update system. Unlike
install.sh, it does not replace your~/.config:curl -fsSL https://raw.githubusercontent.com/rizukirr/hyprsimple/main/bootstrap.sh | bashIt installs hyprsimple to
~/.local/share/hyprsimple, refreshes the helper scripts, and applies every fix you missed as a migration. After that,hyprsimple-updateis all you need.
hyprsimple-update
This pulls the latest hyprsimple, refreshes the helper scripts in ~/.local/bin, installs any newly required packages, and runs pending migrations.
Releases or main
A fresh install follows release tags, so hyprsimple-update on its own moves you from one release to the next and never to an untagged commit.
hyprsimple-update # stay on the channel you are already on
hyprsimple-update --stable # switch to the newest release
hyprsimple-update main # switch to main, and stay there
hyprsimple-update <branch> # switch to any branch of origin, for testing
The choice sticks. Once you run hyprsimple-update main, every later bare hyprsimple-update pulls main until you run hyprsimple-update --stable. There is no config file behind this. The channel is whatever the checkout at ~/.local/share/hyprsimple is on, which you can read with hyprsimple-debug.
Tracking main gets you fixes the day they merge, at the cost of landing on commits no release has covered.
An update never edits your ~/.config files on its own. Only a migration does, and only when a default has to change. Every migration says what it touched.
A migration either makes one specific edit, or saves your version aside first. hyprsimple-refresh-config <path> writes <file>.bak.<timestamp> and prints the diff before replacing. A larger change may move your file to <file>.pre-split.<timestamp> and tell you where it went. Nothing is deleted.
Migrations run once per machine, and the state lives in ~/.local/state/hyprsimple/migrations. A fresh install already ships every fix, so new users skip the history entirely. If one fails you can skip it and carry on. To reset a single config to the shipped default at any time:
hyprsimple-refresh-config hypr/hyprlock.conf
Writing a migration is documented in migrations/README.md.
Some configs cannot be delivered automatically. starship.toml and yazi/yazi.toml are TOML, and that format has no include directive to hang a default off.
When an update changes one of those and you have your own version, hyprsimple-update says so and prints the command to take the new one. It only mentions a file this update changed, so editing something on purpose does not nag you every time.
Theme templates
Writing a theme of your own is covered in THEMING.md, from colors.toml to the files each program reads.
Themes are rendered from the .tpl files in ~/.local/share/hyprsimple/.config/hypr/themes/templates. The install owns them, so a template change reaches you through hyprsimple-update with no migration.
To change one, copy it to ~/.config/hypr/themes/templates.user/ under the same name and edit it there. That directory wins over the install, and a file in it with no shipped counterpart is rendered too, so you can add templates of your own.
Older installs have a copy of the templates at ~/.config/hypr/themes/templates. That directory is not read, and an update removes it once every file in it is one hyprsimple shipped. If you had edited one, the whole directory is left alone and you are told which file it was, so you can move it to templates.user/.
Uninstall
hyprsimple-uninstall.sh removes hyprsimple from your account. It lists what it will do and asks once before changing anything.
It deletes the login entry, plugins, hyprsimple's services, the shell lines the installer added, unchanged scripts and the checkout. Your ~/.config folders move to <name>.hyprsimple-removed so your edits survive, and any .backup from before hyprsimple goes back in place. A checkout with work that exists nowhere else is moved aside too.
Packages and system changes stay. The FAQ says how to undo those by hand. Log out when it finishes, because the session has lost its bar and config.
Audio
SUPER + S opens the bar's volume panel, with a mute switch, a volume slider and every output device. Click a device to make it the default. The microphone has the same panel behind its bar icon. Noise suppression stays on the microphone you choose.
A bluetooth microphone switches the headset into its call profile while it is in use, which lowers playback quality until recording stops. That is how bluetooth headsets work, not something hyprsimple can avoid.
Connecting a bluetooth headset or speaker moves the sound to it. Switching by hand with SUPER + S still wins while that device stays connected, and the next one to connect takes over again. Turn it off with
systemctl --user disable --now hyprsimple-audio-autoswitch.service
Network
wifi on its own rescans and lists the networks in range. wifi "MY NETWORK" connects to one. An open network, or one you have joined before, connects straight away, and a secured one asks for the password.
From a keybind or a script there is nobody to ask, so pass it instead:
wifi "MY NETWORK" "my password"
wifi --help lists both forms. It uses NetworkManager if it is running, and iwd otherwise.
Keybindings
Press SUPER + / for an interactive viewer with fuzzy search.
Applications
| Key | Action |
|---|---|
SUPER + T |
Open terminal (Ghostty) |
SUPER + B |
Open browser (Firefox) |
SUPER + A |
App launcher, a sidebar of the bar |
SUPER + F |
File manager (Nautilus) |
SUPER + V |
Clipboard history, a panel of the bar |
SUPER + M |
Color picker |
Window management
| Key | Action |
|---|---|
SUPER + Q |
Kill active window |
SUPER + W |
Toggle floating |
SUPER + H / J / K / L |
Move focus left / down / up / right |
SUPER + SHIFT + Arrow |
Resize window |
SUPER + LMB drag |
Move window |
SUPER + RMB drag |
Resize window |
Workspaces
| Key | Action |
|---|---|
SUPER + [1-9, 0] |
Switch to workspace 1-10 |
SUPER + SHIFT + [1-9, 0] |
Move window to workspace 1-10 |
SUPER + SHIFT + S |
Move window to scratchpad |
SUPER + CTRL + Arrow |
Move the whole workspace to the monitor in that direction |
SUPER + Scroll |
Cycle through workspaces |
Theming and wallpaper
| Key | Action |
|---|---|
SUPER + SHIFT + T |
Switch theme, from a carousel of wallpapers and colour swatches |
SUPER + SHIFT + W |
Pick a wallpaper from the current theme, same carousel. Its last tile adds one or several from files, Shift + Delete or the bin on a picture deletes it after asking, and the switch under it cycles through them every 30s |
Screenshot
| Key | Action |
|---|---|
Print |
Take a screenshot: drag a region, click a window, or click where there is none for the whole screen |
The screen freezes while you pick, and Escape takes nothing. The picture is saved to ~/Pictures/Screenshots and copied to the clipboard, both.
Screen recording
| Key | Action |
|---|---|
SUPER + R |
Open the recording menu, a panel of the bar, which starts a recording or stops the one that is running. Recording a window asks which one, from a list |
The menu offers a region, a window or the whole screen, each with microphone audio, system audio, or none. A window is recorded as the area it covered when you picked it, so moving it or covering it shows in the recording. While something is recording it offers to stop instead, so the same key both starts and stops.
Recording uses wl-screenrec where it can and wf-recorder otherwise, and NVIDIA machines prefer wf-recorder. Only wf-recorder is required. It comes from the official repositories, so recording still works if the wl-screenrec build fails during install.
Media and brightness
| Key | Action |
|---|---|
Volume Up / Down |
Adjust volume |
Mute |
Toggle mute |
Mic Mute |
Toggle microphone mute |
Play / Pause |
Media play/pause |
Next / Prev |
Media next/previous track |
Brightness Up / Down |
Adjust screen brightness |
Kbd Brightness Up / Down |
Adjust keyboard backlight |
System
| Key | Action |
|---|---|
SUPER + ESC |
Power menu, a panel of the bar |
SUPER + SHIFT + L |
Lock screen |
SUPER + X |
Exit Hyprland |
CTRL + ESC |
Hide or show the bar |
SUPER + N |
Toggle nightlight |
SUPER + D |
Dismiss notifications |
SUPER + SHIFT + I |
Toggle idle lock |
SUPER + S |
Open the volume panel, to set the volume and choose a speaker |
SUPER + ALT + S |
Open the microphone panel |
SUPER + SHIFT + N |
Open the network panel |
SUPER + SHIFT + B |
Open the bluetooth panel |
SUPER + SHIFT + D |
Open the notifications panel |
SUPER + C |
Open the calendar panel |
SUPER + I |
Open the system panel: power mode, CPU, memory and GPU |
SUPER + SHIFT + M |
Toggle monitor mirroring |
SUPER + CTRL + V |
Toggle virtual mirror |
SUPER + / |
Show all keybindings, in a searchable panel of the bar |
Scripts
Helper scripts live in .local/bin and are installed to ~/.local/bin, which is on PATH. Most are wired to keybindings or the bar, and all of them can be run from a terminal.
Audio
| Script | Description |
|---|---|
audio-switch.sh |
Cycle through available audio output devices, for a bind of your own |
hyprsimple-clipboard-menu.sh |
Opens the bar's clipboard history panel, behind SUPER + V |
volume-notify.sh |
Show the current PipeWire volume as a notification |
record-audio.sh |
Record audio from the default input to ~/Music |
Display, theme and wallpaper
| Script | Description |
|---|---|
brightness-notify.sh |
Show the current screen brightness as a notification |
keyboard-brightness.sh |
Control the keyboard backlight (up / down / cycle) |
toggle-nightlight.sh |
Toggle a warm screen temperature via hyprsunset |
theme-switcher.sh |
Switch theme via the visual picker, or apply one directly by name |
theme-apply-templates.sh |
Generate themed app configs from a theme's colors.toml |
wallpaper-switcher.sh |
Pick, add, delete or cycle a wallpaper within the current theme. next cycles, for a bind of your own |
hyprsimple-theme-picker.sh |
List one row per theme, with its wallpaper and colour swatches, for the bar's theme picker |
hyprsimple-wallpaper-picker.sh |
List one row per wallpaper in the current theme, newest first, for the bar's wallpaper picker |
hyprsimple-thumbnails.sh |
Swap the image in each of those rows for a small cached thumbnail, which is what the pickers show |
live-wallpaper-toggle.sh |
Turn live wallpaper on or off (cycling backgrounds or a static one), behind the switch in the wallpaper picker |
monitor-mirror-toggle.sh |
Toggle between extending to and mirroring on an external monitor |
virtual-mirror-toggle.sh |
Mirror a monitor into a window (via wl-mirror) for screen sharing |
Screenshot and recording
| Script | Description |
|---|---|
screenshot.sh |
Take a screenshot. smart, behind Print, picks on a frozen screen and both saves and copies. The other modes capture one thing: region / window / monitor, or region-clipboard / window-clipboard / clipboard |
screen-record.sh |
Start or stop screen recording (region, window or output, with mic, internal, or no audio) |
hyprsimple-record-menu.sh |
Opens the bar's record panel, behind SUPER + R, which picks what to record and starts or stops it |
screen-record-active.sh |
Report whether a screen recording is running |
Network
| Script | Description |
|---|---|
hyprsimple-audio-autoswitch.sh |
Move the sound to a bluetooth device when one connects, run as a user service |
wifi.sh |
List and connect to WiFi networks, asking for the password when one is needed |
hyprsimple-network-setup.sh |
Make NetworkManager run the network, which the bar's network panel needs. A machine on iwd is moved over with its saved networks, and moved back if the network does not return. One already on NetworkManager is left alone |
wifi-powersave.sh |
Toggle WiFi power saving (on / off) |
hotspot.sh |
Create a WiFi hotspot with internet sharing |
setup-dns.sh |
Configure the DNS provider (Cloudflare / Google / DHCP) |
System and power
| Script | Description |
|---|---|
battery-monitor.sh |
At a low battery, warns, dims the screen and switches to power saver. On the charger, puts both back and says so |
bluetooth-toggle.sh |
Toggle Bluetooth adapter power |
toggle_cpu_mode.sh |
Switch CPU governor between performance and powersave |
hyprsimple-hw-intel-laptop.sh |
Exit 0 on an Intel laptop new enough for thermald (used as a condition) |
toggle-idle.sh |
Toggle hypridle (lock on idle) on or off |
hypr-logout.sh |
Close all windows and stop the Hyprland session |
Input and notifications
| Script | Description |
|---|---|
capslock-notify.sh |
Notify on Caps Lock state changes |
notification-dismiss.sh |
Dismiss every notification on screen |
Search and keybindings
| Script | Description |
|---|---|
search.sh |
Fuzzy file finder (ripgrep + fzf) that opens the result in nvim |
search_by_keyword.sh |
Fuzzy content search (ripgrep + fzf) that opens the match in nvim |
show-keybindings.sh |
Open the bar's keybindings panel, a searchable list of every Hyprland keybinding. --list prints them instead |
hyprsimple management
| Script | Description |
|---|---|
hyprsimple-update.sh |
Pull hyprsimple, refresh scripts and packages, run pending migrations. --stable or <branch> switches channel |
hyprsimple-plugin |
Install, enable, disable, update, list or remove trusted external plugins |
hyprsimple-migrate.sh |
Run any migrations that have not run on this machine yet |
hyprsimple-refresh-config.sh |
Reset one ~/.config file to the shipped default, with a backup and a diff |
hyprsimple-restart-bar.sh |
Start or restart the bar. --if-running restarts a running bar and does nothing otherwise, --toggle hides or shows a running bar and starts a stopped one |
hyprsimple-debug.sh |
Collect system diagnostics into one file to view, save, or upload |
hyprsimple-session.sh |
Add a "Hyprsimple" entry to the login screen, or remove it. It starts the same config as the stock Hyprland entry |
hyprsimple-uninstall.sh |
Remove hyprsimple from your account and restore your backups. Packages and system changes stay |
hyprsimple-dev-add-migration.sh |
Create a new migration file (for contributors) |
External plugins
See the plugin author guide for the manifest and QML contract.
Run hyprsimple-plugin install OWNER/REPO to install the newest release of a trusted plugin, or add --branch main to lock it to a branch. hyprsimple-plugin update ID --stable returns it to releases. Use hyprsimple-plugin list, disable ID, enable ID, update ID or remove ID to manage it. Plugins run code from their repository, so review it before installing.
Plugin code lives in ~/.local/share/hyprsimple-plugins, outside the core checkout. Enablement, placement and plugin settings live in ~/.config/hyprsimple/plugins.json. Developers can override the code directory with HYPRSIMPLE_PLUGIN_ROOT. Plugins bind no keys. Each one names a panel alias, and you bind a key to it in ~/.config/hypr/bindings/applications.lua. The default Muslimtify plugin's alias is prayer:
hl.bind("SUPER + P", hl.dsp.exec_cmd(vars.barPanel .. "prayer"), { description = "Prayer Times (panel)" })
If the plugin is installed but disabled, run hyprsimple-plugin enable muslimtify. If the download failed, retry hyprsimple-plugin install https://github.com/muslimtify-org/muslimtify-hyprsimple.git. For an enabled plugin whose daemon is stopped, run muslimtify daemon install first. Removing the plugin keeps application settings and installed packages.
The delivery suites need a checkout of the published plugin at 2f2b9028b3833e6cb4dc25b5b138fc18ef74bfea. Set MUSLIMTIFY_PLUGIN_FIXTURE to that checkout, then run bash test/plugin-migration-test.sh and bash test/plugin-default-install-test.sh. The local default is /tmp/muslimtify-hyprsimple. CI fetches the pinned fixture into RUNNER_TEMP before running either suite. The suites map the public URL to that local origin and perform no network, package or service operations.
Shell init and internal helpers
These are sourced by other files rather than run directly.
| Script | Description |
|---|---|
bashrc.sh / zsh.sh / fish.fish |
Per-shell init (zoxide, fzf, starship, aliases) sourced from your shell's rc file |
terminal.sh |
Detect your login shell and wire the matching init script into its rc file |
hypr-helpers.sh |
Shared hyprpaper helper functions used by the wallpaper scripts |
hyprsimple-aur-helper.sh |
Reports which AUR helper is installed, so the installer, the updater and the plugin manager all use the one you already have |
hyprsimple-require.sh |
Loads the helpers a script needs, and stops it rather than letting it run with them missing |
hyprsimple-theme-deliver.sh |
Puts a theme's generated files where each program reads them, shared by the theme switcher and the updater |
hyprsimple-hw-battery.sh |
Exits 0 when this machine has a battery, which is how hyprsimple decides it is a laptop |
hyprsimple-hw-nvidia.sh |
Exits 0 when this machine has an NVIDIA GPU |
FAQ
Troubleshooting and known issues, such as the NVIDIA boot hang and the Plymouth blank-screen splash, are documented in FAQ.md.
License
MIT