Build a proper settings application for modular Linux desktops.
The product should provide a polished macOS/Windows-style system settings experience for Hyprland and Arch-based Linux systems, while preserving the transparency, composability, and user ownership expected by experienced Linux users.
1. Product mission
Build a control plane for a user's existing Linux desktop. The application must not require the user to adopt a specific dotfile distribution, shell, bar, terminal, launcher, notification daemon, or theme system.
What this product is
- A graphical settings application.
- A configuration orchestration layer.
- A plugin framework for app-specific settings.
- A theme and profile management system.
- A safe GUI over Linux configuration files and runtime APIs.
What this product is not
- Not another dotfiles repository.
- Not a replacement Linux distro.
- Not a fork of Hyprland.
- Not a system daemon that owns all user configuration.
- Not a GUI that blindly rewrites arbitrary config files.
2. Non-negotiable product principles
User owns their configuration
Never treat user-authored config as generated state. Generated files must be clearly separated and recoverable.
GUI and CLI share the same core
No duplicate business logic. All reads, writes, validation, snapshots, diffs, profile switches and plugin actions must pass through one settings core.
Prefer adapters over assumptions
Detect the installed stack and use adapters for Hyprland, Waybar, Quickshell, Alacritty, Yazi, Mako, etc.
Every write must be reversible
Take snapshots before mutation, offer preview/diff where practical, and expose restore operations.
Do not hide Linux
Expose generated configuration, file locations and runtime commands. The product simplifies Linux; it does not pretend Linux is something else.
Progressive disclosure
Normal users see controls; power users can open advanced settings, raw config, generated output, logs and diagnostics.
Fail safely
A malformed plugin, failed reload or invalid config must not leave the desktop unusable.
Local-first
No cloud account is required. Settings, themes, profiles and backups work offline.
3. Scope and product boundaries
V1 should solve the configuration problems most specific to modular Wayland desktops. Do not begin by rebuilding GNOME Settings.
| Priority | Subsystem | V1 expectation |
|---|---|---|
| P0 | Appearance | Themes, colors, fonts, icons, cursors, wallpaper integration. |
| P0 | Hyprland | Gaps, borders, rounding, opacity, blur, animation, layouts, workspaces. |
| P0 | Displays | Monitor discovery, arrangement, resolution, refresh rate, scale, rotation, VRR when supported. |
| P0 | Keybindings | Read, add, edit, delete, conflict detection, built-in action templates. |
| P0 | App plugins | At least Alacritty + Yazi + one bar/shell integration. |
| P1 | Wallpaper | Library, per-monitor selection, history, favorites, optional palette extraction. |
| P1 | Startup / idle | Autostart, Hypridle, Hyprlock and session startup integration. |
| P1 | Default apps | Terminal, browser, file manager, editor, image/video/PDF viewer. |
| P1 | Window rules | Visual rule editor with validation. |
| P1 | Profiles | Laptop/desk/gaming/presentation style config bundles. |
| P2 | Audio / network / Bluetooth / users | Post-V1 unless architecture already exposes reliable system APIs. |
| P2 | Package management | Do not include in MVP. Treat as a separate later subsystem. |
4. UX expectations
Beginner path
Install → launch → scan desktop → see only relevant settings → change a value → preview/apply → desktop reloads automatically.
Power-user path
Inspect exact config paths, generated fragments, command invocations, diff, logs and per-plugin behavior. Allow opting out of management per subsystem.
- Use a desktop-settings information architecture: persistent sidebar, section detail view, search.
- Controls should map to semantic concepts, not configuration syntax.
- Use immediate preview only when safe; otherwise require Apply.
- Any destructive or session-impacting action must clearly explain impact before execution.
- Search should find both human terms (“rounded corners”) and underlying concepts (
rounding). - Unavailable settings must explain why they are unavailable instead of silently disappearing when that would confuse the user.
5. System architecture
┌──────────────────────────────────────────────────────┐
│ Presentation │
│ │
│ Desktop GUI CLI │
└──────────────┬───────────────────────┬───────────────┘
│ │
└───────────┬───────────┘
▼
┌──────────────────────────────────────────────────────┐
│ Settings Core │
│ │
│ read · validate · diff · apply · snapshot · restore │
│ profiles · discovery · dependency graph · events │
└──────────────┬───────────────────────┬───────────────┘
│ │
┌────────▼────────┐ ┌──────▼────────┐
│ Desktop adapters│ │ App plugins │
│ │ │ │
│ Hyprland │ │ Alacritty │
│ Hypridle │ │ Yazi │
│ Hyprlock │ │ Waybar │
│ Wallpaper │ │ Quickshell │
└────────┬────────┘ └──────┬────────┘
│ │
└───────────┬───────────┘
▼
Files / IPC / DBus
system commands
runtime sockets
hyprland.conf, invoke hyprctl, edit Alacritty files or manipulate system state.
It calls the Settings Core, which delegates to a versioned adapter/plugin.
6. Canonical settings model
Internally, settings should be represented independently of any target application's file format.
{
"path": "desktop.hyprland.general.gaps_out",
"type": "integer",
"value": 10,
"default": 5,
"constraints": { "min": 0, "max": 100 },
"source": "hyprland",
"restartPolicy": "reload",
"managed": true,
"dirty": false
}
Every setting definition should support, where applicable:
- Stable ID/path.
- Display label and description.
- Type: boolean, integer, float, string, enum, color, file, directory, command, keybinding, list, object.
- Default value and current resolved value.
- Validation constraints.
- Visibility conditions and dependency conditions.
- Restart/reload requirements.
- Source plugin/adapter.
- Whether the value is user-owned, generated, inherited or unmanaged.
7. Configuration safety model
This is the most important engineering requirement in the entire project.
Preferred strategy: generated override fragments
~/.config/hypr/hyprland.conf
├─ user's normal configuration
└─ source = ~/.config/modular-settings/generated/hyprland.conf
~/.config/modular-settings/
├─ state/
├─ generated/
│ ├─ hyprland.conf
│ ├─ theme/
│ └─ ...
├─ snapshots/
├─ profiles/
└─ plugins/
Mutation transaction
- Read current state.
- Validate proposed state.
- Generate output into a temporary file.
- Validate generated configuration with the target adapter where possible.
- Create snapshot of currently managed output.
- Atomically replace generated file.
- Request target reload.
- Verify success.
- If verification fails, restore snapshot automatically.
- Return structured success/error information to GUI/CLI.
Required backup behavior
- Automatic snapshots before every write transaction.
- Retention policy configurable; reasonable default such as last 20 snapshots per component.
- Named manual snapshots.
- Full profile/export snapshots.
- One-click rollback from GUI and CLI.
8. Plugin system
The plugin framework is a first-class product feature, not an implementation detail. The core team should not need to hard-code every Linux application.
plugin/
├─ plugin.toml
├─ schema.json
├─ icon.svg
├─ adapter
│ └─ ...
├─ migrations/
└─ README.md
Example manifest
id = "alacritty"
name = "Alacritty"
version = "1.0.0"
api_version = 1
[detect]
binary = "alacritty"
config = "~/.config/alacritty/alacritty.toml"
[capabilities]
read = true
write = true
preview = false
reload = false
Example schema concept
{
"groups": [
{
"id": "font",
"label": "Font",
"settings": [
{
"id": "font.size",
"type": "number",
"label": "Font Size",
"min": 6,
"max": 36,
"step": 0.5
}
]
}
]
}
Plugin API requirements
- detect() — determine whether plugin is applicable.
- read() — resolve current values.
- validate() — validate requested changes.
- plan() — produce a human-readable mutation plan/diff.
- apply() — perform a transaction through core-provided safe filesystem primitives.
- reload() — reload target when possible.
- health() — provide diagnostic status.
9. Theme engine
Themes should use semantic tokens, then adapters map those tokens into target applications.
[meta]
name = "Everforest Dark"
[colors]
background = "#272e33"
surface = "#2e383c"
surface_alt = "#374145"
foreground = "#d3c6aa"
muted = "#859289"
accent = "#a7c080"
accent_alt = "#83c092"
red = "#e67e80"
orange = "#e69875"
yellow = "#dbbc7f"
green = "#a7c080"
blue = "#7fbbb3"
purple = "#d699b6"
Theme targets should be opt-in per application. A user must be able to apply a desktop theme without forcing their editor or terminal to change.
- Hyprland border/colors.
- GTK and Qt where safely supported.
- Terminal emulators.
- Waybar / Quickshell.
- Rofi / launchers.
- Mako / SwayNC.
- Hyprlock.
- Yazi.
- Optional adapters for Neovim and other developer tools.
10. Settings modules
Appearance
Theme, light/dark mode, GTK/Qt, fonts, icons, cursor, borders, radius, opacity.
Wallpaper
Library, per monitor, favorites, history, randomization, rotation, palette extraction.
Desktop
Hyprland general, decoration, animations, layout, workspaces, gestures.
Displays
Drag arrangement, resolution, Hz, scaling, transforms, VRR and workspace assignment.
Input
Keyboard layout, repeat, mouse, touchpad, natural scrolling, sensitivity and gestures.
Keybindings
Visual shortcut editor, actions, commands, duplicate/conflict detection.
Window Rules
Match by class/title/workspace with visual actions and validation.
Startup
Hyprland exec-once entries and optional user systemd service integration.
Lock & Idle
Hyprlock appearance plus Hypridle timeout/suspend/DPMS actions.
Apps
Dynamically populated from installed plugins and detected applications.
Defaults
Terminal, browser, file manager, editor, media handlers and MIME defaults where appropriate.
Advanced
Raw managed config, logs, environment, reload controls, diagnostics, snapshots.
11. CLI requirements
# inspection
mlsettings get desktop.hyprland.general.gaps_out
mlsettings list
mlsettings plugins list
mlsettings doctor
# writes
mlsettings set desktop.hyprland.general.gaps_out 10
mlsettings theme apply everforest
mlsettings wallpaper set ~/Pictures/wallpaper.png
# profiles
mlsettings profile list
mlsettings profile apply gaming
# safety
mlsettings diff
mlsettings snapshot create before-rice-change
mlsettings snapshot list
mlsettings snapshot restore <id>
# debugging
mlsettings config paths
mlsettings logs
mlsettings plugin inspect alacritty
The CLI should support machine-readable output, preferably --json, so shell scripts and external tools can integrate with the settings core.
12. Profiles
Profiles are named bundles of settings and optional runtime actions.
profiles/
├─ laptop.toml
├─ desk.toml
├─ gaming.toml
└─ presentation.toml
| Profile | Typical configuration |
|---|---|
| Laptop | Lower refresh rate, power-saving behavior, smaller gaps, laptop display only. |
| Desk | External display arrangement, preferred refresh rates, normal animations. |
| Gaming | VRR, minimal blur, no heavy animations, performance-related session settings where supported. |
| Presentation | Display mirroring, notifications disabled, simplified workspace behavior. |
Profile application must itself be transactional: either all applicable changes succeed, or failed operations are reported and rollback occurs according to component safety policies.
13. Desktop discovery
First launch should inspect the system and construct a settings interface relevant to the current machine.
Desktop scan
────────────────────
Hyprland detected
Hyprlock detected
Hypridle detected
Quickshell detected
Alacritty detected
Yazi detected
Mako not installed
Waybar not installed
Matugen not installed
Discovery should inspect:
- Available binaries in
PATH. - Known config locations.
- Hyprland runtime environment and IPC/socket availability.
- User services where relevant.
- Optional dependencies required by plugins.
Discovery results must be cached but refreshable. The application must tolerate software being installed or removed while it is running.
14. Recommended implementation stack
| Layer | Recommendation | Reason |
|---|---|---|
| Core | Rust | Strong typing, safe filesystem work, excellent CLI/system integration, distributable static-ish binaries. |
| GUI | GTK4 + libadwaita, or another production-capable Rust UI stack | Good Linux integration and accessibility. Do not couple core behavior to toolkit. |
| CLI | Rust + clap | Shared domain types and easy packaging. |
| Serialization | serde + TOML/JSON/YAML adapters | Config ecosystem compatibility. |
| State | Small local SQLite DB only if needed; otherwise files | Use DB for metadata/index/history, not as hidden source of truth for Linux config. |
| IPC | In-process initially; optional DBus/service later | Avoid unnecessary daemon architecture in MVP. |
| Tests | Rust unit/integration + fixture-based config tests | Lossless/safe config behavior must be heavily regression tested. |
15. Repository layout
modular-linux-settings/
├─ Cargo.toml
├─ README.md
├─ LICENSE
├─ docs/
│ ├─ architecture.md
│ ├─ plugin-api.md
│ ├─ config-safety.md
│ └─ contributing.md
├─ crates/
│ ├─ core/
│ ├─ cli/
│ ├─ gui/
│ ├─ plugin-sdk/
│ ├─ config-io/
│ ├─ snapshots/
│ └─ diagnostics/
├─ adapters/
│ ├─ hyprland/
│ ├─ hypridle/
│ ├─ hyprlock/
│ └─ wallpaper/
├─ plugins/
│ ├─ alacritty/
│ ├─ yazi/
│ ├─ waybar/
│ └─ quickshell/
├─ themes/
│ ├─ everforest/
│ └─ example/
├─ fixtures/
│ ├─ hyprland/
│ ├─ alacritty/
│ └─ yazi/
├─ packaging/
│ ├─ arch/
│ └─ flatpak/ # optional later, assess permission constraints first
└─ scripts/
16. Implementation phases
Foundation and technical spike
Prove safe read/write/reload behavior before investing in UI.
- Initialize workspace and CI.
- Define canonical settings types and error model.
- Implement filesystem abstraction with atomic writes.
- Implement snapshot manager.
- Implement Hyprland environment/runtime detection.
- Create one end-to-end setting:
gaps_outread → change → generated override → reload → rollback.
Settings core + Hyprland adapter
- General/decorations/animations/layout settings.
- Hyprland config generation.
- Runtime reload and health verification.
- Diff generation.
- CLI get/set/diff/snapshot/restore.
- Fixture coverage for multiple user config layouts.
GUI shell
- Sidebar navigation.
- Search.
- Reusable setting controls generated from schemas.
- Apply/revert workflow.
- Inline validation and error presentation.
- Advanced view showing source and generated config.
Displays and keybindings
- Monitor discovery.
- Visual monitor arrangement.
- Resolution/refresh/scale/rotation.
- Safe monitor configuration preview/recovery strategy.
- Parse existing Hyprland keybindings.
- Add/edit/remove managed bindings.
- Conflict detection.
Plugin SDK and first app integrations
- Versioned plugin manifest.
- Detection API.
- Schema-driven UI API.
- Permission/capability model.
- Alacritty plugin.
- Yazi plugin.
- Waybar or Quickshell plugin.
- Plugin developer documentation.
Theme and wallpaper engine
- Semantic theme token format.
- Theme adapters.
- Per-application theme opt-in.
- Wallpaper library/index.
- Per-monitor wallpaper.
- Wallpaper → palette integration as optional capability.
Profiles, diagnostics and polish
- Profiles and profile switch transactions.
doctordiagnostics.- Crash-safe recovery.
- Accessibility pass.
- Keyboard-only navigation.
- Performance pass.
- Arch package and AUR-ready packaging.
Post-MVP system integrations
Only after core architecture is stable: NetworkManager, BlueZ, PipeWire, power, user/account metadata, package/default-app conveniences and additional compositors such as Niri or Sway.
17. Testing requirements
Unit tests
- Schema validation.
- Setting resolution.
- Theme token mapping.
- Conflict detection.
- Snapshot rotation.
- Path expansion and safe-path checks.
Fixture tests
Every adapter/plugin should include real-world configuration fixtures:
fixtures/hyprland/
├─ minimal.conf
├─ sourced-files.conf
├─ comments-heavy.conf
├─ unusual-formatting.conf
├─ duplicate-settings.conf
└─ invalid.conf
Transaction tests
- Write succeeds → reload succeeds.
- Write succeeds → reload fails → rollback occurs.
- Disk full / permission denied.
- Plugin crashes during plan/apply.
- Configuration changed externally between read and apply.
GUI tests
- Keyboard navigation.
- Search.
- Validation states.
- Apply/revert behavior.
- Unavailable dependency states.
- Dynamic plugin installation/removal.
18. Security and privilege rules
- Run entirely as the user by default.
- Never run the whole GUI as root.
- Use privilege escalation only for a narrowly scoped action that actually requires it.
- Never interpolate untrusted strings into shell commands.
- Prefer direct process execution with argument arrays instead of
sh -c. - Resolve and validate filesystem paths before writes.
- Plugins must declare capabilities.
- Third-party plugin code must be considered untrusted.
- Do not transmit configuration data off-device unless the user explicitly enables a future cloud feature.
19. MVP release criteria
The project is not ready for a public MVP until all of the following are true:
- Installs cleanly on a fresh Arch + Hyprland environment.
- Launches without requiring root.
- Detects Hyprland and relevant supported components.
- Can configure appearance, core Hyprland options, displays and keybindings.
- Supports at least three app/component plugins.
- All managed writes are atomic or transactional.
- Automatic snapshots and rollback work.
- Externally edited configs are detected instead of silently overwritten.
- GUI and CLI produce the same resulting state.
- Application remains usable if one plugin fails.
- Logs contain enough context to debug failures without exposing secrets.
- Documentation explains exactly which files the application owns.
- Uninstalling the program does not destroy the user's original configuration.
20. Instructions for the implementation agent
- Work phase-by-phase. Do not start later modules before the current phase's exit criterion works.
- Keep the project buildable. Every meaningful commit should compile and tests should pass.
- Do not invent APIs silently. Document important domain interfaces and plugin contracts as they are introduced.
- No destructive whole-file rewrites. Use generated overrides or verified lossless transformations.
- Never modify unrelated settings. One requested change must produce the narrowest possible mutation.
- Back up before writes. Every managed mutation participates in snapshot/transaction infrastructure.
- Separate domain logic from UI. The GUI is a client of the Settings Core.
- Prefer structured process execution. Avoid shell strings.
- Do not introduce a background daemon unless required by a demonstrated feature.
- Do not add cloud services, telemetry or accounts in MVP.
- Do not bundle opinionated dotfiles. Example themes/plugins are acceptable; replacing the user's desktop is not.
- Do not assume Waybar/Kitty/Rofi/etc. Detect components and populate UI dynamically.
- Support external edits. Detect file changes and reconcile/refresh rather than overwriting stale state.
- Return structured errors. The UI must be able to distinguish validation, permission, missing dependency, parse, reload and rollback failures.
- Add tests with each adapter feature. A new config mutation without regression fixtures is incomplete.
- Keep public plugin APIs versioned. Avoid breaking third-party plugins without an explicit migration/version strategy.
- Document ownership. Every generated file must have a visible header where the target format permits comments.
- Implement diagnostics early. Every adapter should expose detection and health information useful to
doctor. - Design for future compositor adapters, but implement Hyprland first. Do not prematurely build abstractions that have no Hyprland use.
- When uncertain, preserve the user's current working desktop. Safety is more important than applying a requested cosmetic change.
Required agent progress reporting
At the end of each implementation phase, produce:
- What was implemented.
- Files/modules added or changed.
- Tests added and their status.
- Known limitations.
- Manual verification steps.
- Whether the phase exit criterion is fully met.
- Any architecture decision that deviated from this specification and the reason.
21. Definition of long-term success
The project succeeds when an Arch/Hyprland user can adopt it without surrendering control of their desktop, and a plugin author can add support for another application without changing the core application.
V1 identity
A highly polished Hyprland settings application with safe app configuration integrations.
Long-term identity
A compositor-agnostic settings framework for modular Linux desktops: Hyprland first, potentially Niri, Sway, River, Labwc and others later.