Monday, April 20, 2026

Griffin and where it is at

Griffin Linux: A Better Way to Run Linux or a Windows Switcher's Dream Machine

Part overview, part technical breakdown. Everything currently available, and why it exists.

It handles performance tuning, hardware control, process management, and system integration automatically, without replacing your distro.
Think of it as the infrastructure Linux never shipped.

Quick links: Discord: https://discord.gg/7fEt5W7DPh | Patreon: https://www.patreon.com/c/BobbyComet | Ko-fi: https://ko-fi.com/bobby60908


What Griffin Actually Is

Griffin is not a Linux distribution. It is a coordinated set of tools designed to sit on top of a Debian or Ubuntu-based system and make it behave more like a finished, coherent desktop experience rather than a collection of parts you are expected to configure yourself.

That distinction matters more than it might seem at first. Griffin does not replace your package manager, your kernel, your desktop environment, or your distro. It adds a layer of tooling that handles the things Linux traditionally leaves entirely to the user: performance tuning, hardware configuration, fan control, process management, kernel parameter optimization, and the broad category of problems that send new users to forums within their first week. The system you already have stays intact. Griffin just makes it work better and makes it easier to understand when something goes wrong.

The project started as a set of independent scripts. One handled kernel parameters. Another managed fan control. A third turned websites into desktop apps. Over time, those scripts became proper tools, and the tools started sharing state with each other. That coordination is what separates Griffin from a random collection of utilities you could find separately on GitHub. The tools are built to work together, and in several cases, they actively do so at runtime, passing state between each other without requiring you to wire anything up manually.

Griffin currently targets Debian and Ubuntu-based systems for its core toolset. A handful of tools have broader compatibility by nature of how they are built, and those are noted in each section below. An official installer for the full suite is planned, which will let you bring Griffin to any compatible system without starting from scratch.

One thing worth addressing upfront: Griffin was originally planned as a full Linux distribution. That direction was paused due to US legislation around age verification that would create serious complications for shipping and distributing a full Linux distribution. If that legislation is reversed or fails to pass, the distribution will be revisited. Nothing about the tools, the vision, or the experience has changed because of this. The layer approach is, if anything, a cleaner design, because it means Griffin works with whatever Ubuntu-based system you already have, rather than requiring a full reinstall.


For Windows Users: What This Actually Means

When you switch from Windows to Linux, you quickly discover that Linux does not have equivalents for a lot of things you took for granted. There is no fan control software that works like Argus Monitor or FanControl out of the box. There is no straightforward way to install a different kernel without learning what a PPA is and why it matters. There is no built-in way to turn a website into a desktop app with its own isolated profile, its own icon, and its own taskbar entry. There is no tool quietly watching your background processes to make sure a rogue system update check does not tank your frame rate in the middle of a game. There is no single place to swap GPU drivers safely when you change hardware brands.

On Windows, most of this infrastructure existed in some form, often invisibly, and you never had to think about it. On Linux, you either build it yourself, find scattered community tools and hope they still work on your kernel version, or go without and accept that your desktop is less capable than it could be.

Griffin is the infrastructure. You install it on top of the Ubuntu-based system you already have, and the pieces are there. You do not need to know what sysctl is or why it matters. You do not need to read a wiki page about CPU governors and decide which one is right for your workload. You do not need to learn the difference between nice and ionice, or understand what cgroups are, or figure out why your fan runs at full speed when you are just browsing the web. The tools handle that. They talk to each other. They stay out of your way unless something genuinely needs your attention.

That is the goal. Not to hide Linux from you, but to make sure the first months of using it feel like using a computer that already works, not like assembling one.


For Linux Users: The Technical Design

The more interesting question for experienced Linux users is how the tools coordinate without a central broker or shared daemon creating a single point of failure.

The answer is shared state files and runtime detection. Kernel Autotune writes a state.json to /etc/kernel-autotune/ that records the current kernel type, the hardware profile (desktop, laptop, or handheld), and which parameters were applied. Other tools read this file to understand what the system looks like at a low level without having to re-detect everything themselves. Process Sentry reads from it to understand the gaming context and adjust its throttle behavior accordingly. Game Tune Hub wraps Steam's executable so the resulting process tree carries a detectable gamemoded signature that Sentry picks up at runtime to trigger its gaming behavior, including backing off on background process throttling and requesting Gamemode via D-Bus.

Fan Hub connects to the OpenRGB SDK server over TCP rather than requiring OpenRGB to remain open as a visible application. Once the server is started, Fan Hub controls RGB and fan curves headlessly. This is a deliberate design choice: it means the tool works as a background service without forcing a full GUI application to stay open.

XKM installs kernels and signals Kernel Autotune to reapply its configuration profile to the new kernel by updating the shared state. The tuning follows the kernel rather than being tied to a specific version, so installing a Xanmod or Liquorix kernel through XKM gives you that kernel already configured correctly rather than requiring a manual re-run of the tuning script.

Process Sentry's exemptions are also integration points. Appify apps are automatically excluded from throttling because Sentry checks whether a browser process has ~/.pwa_manager/profiles/ in its command line. This means cloud gaming apps launched through Appify get full CPU priority without any manual configuration. The config file ships with that exemption enabled by default.

None of this coordination requires a central broker. Each tool understands its own relationship to the others, handles its own side of the integration, and degrades gracefully when a related tool is not present. That design makes each tool independently useful even if you only install one of them, while delivering tighter integration when the full set is in place.


The Tools: What Is Available Now

What follows covers every tool currently available. Each section explains what the tool does for everyday users first, then goes into the technical details for those who want it. These are not shallow overviews. If you want to understand exactly how something works, the information is here.


APPIFY Version 2.1.4 GitHub: https://github.com/bobbycomet/Appify

What it is for Windows users:

On Windows, you could install apps like Discord, Gmail, Twitch, or a cloud gaming service as standalone desktop apps with their own icons, their own taskbar entries, and no browser tab in sight. Some of these are installed through PWA support in Edge or Chrome. Others had native installers. Either way, they behaved like real apps rather than shortcuts to a browser tab.

Linux has never had a clean, consistent way to do this. Browser shortcuts technically work, but they share your main browser profile, which means your history, cookies, session data, and login state bleed between the shortcut app and your regular browsing. There is no isolation. Firefox has no built-in PWA support at all. Tools like GNOME Web and nativefier exist, but they require extra setup, have limited browser support, or rely on hacks like userChrome.css that break silently whenever Firefox updates its internal UI structure.

Appify gives you properly isolated desktop apps from any URL, using whichever browser you already have installed. You open the app, search for the site you want, pick a browser, optionally configure extensions, and click install. The typical install time is under one second. No terminal. No config files. No manual steps. The app appears in your application launcher with its own icon, launches in its own isolated browser profile, and behaves like a native application.

For cloud gaming specifically, Appify includes kiosk mode, which launches the app in a full-screen dedicated window with no browser chrome, no tab bar, and no address bar. This makes services like Xbox Cloud Gaming, GeForce NOW, Amazon Luna, and Boosteroid feel much closer to a native launcher. Appify also handles controller support differences between browsers: Firefox is the recommended browser for most cloud gaming services because it has native gamepad support that works without additional flags or portal dependencies, while Chromium-based browsers require WebHID to be explicitly enabled and need the xdg-desktop-portal stack to be running. Appify handles all of this automatically, checks whether your portal stack is ready, and warns you in the UI if it is not.

The technical side:

Appify stores all of its configuration and profiles in ~/.config/appify/. Each installed app gets an isolated browser profile directory under ~/.config/appify/profiles/, a shell wrapper script in ~/.config/appify/scripts/, and a .desktop file written to ~/.local/share/applications/ so the app appears in your application launcher with a proper icon.

The shell wrapper is more than just a launch command. It sets nice and ionice priorities to give the app appropriate CPU and I/O scheduling, applies GPU acceleration flags appropriate to the detected display server, enables WebHID flags for gamepad support on Chromium-based browsers, and selects Wayland or X11 backend flags based on the compositor in use. Appify detects the compositor at install time and writes the correct flags into the wrapper. Supported compositors include KDE Plasma, GNOME, Hyprland, Sway, COSMIC, and other Wayland environments, with X11 as the fallback.

For Firefox profiles, Appify writes a user.js file to the profile directory. This file suppresses all first-run UI, telemetry, sync prompts, new-tab page content, and session restore dialogs, and locks the homepage to the app's URL. This file is regenerated on every install, so future Appify updates that add new preference entries will apply to existing profiles automatically. If you want to add your own Firefox preferences to a profile, the correct place is a user-overrides.js file in the same directory, which will not be overwritten.

The Firefox PWA implementation deliberately avoids userChrome.css. This is a meaningful choice. The traditional approach of hiding Firefox's browser chrome uses CSS targeting Firefox's internal XUL UI structure, which changes frequently and silently across Firefox updates. Appify instead uses Firefox's --kiosk flag combined with the isolated profile and user.js configuration to produce a standalone app window that is stable across Firefox updates because it uses documented, supported features rather than internal CSS hooks.

Browser detection checks for native installs, Flatpak, and Snap installations in that order. For Chromium-based browsers, WebHID flags are configured automatically. For Xbox Cloud Gaming specifically, Appify defaults to a Chromium-based browser with WebHID pre-configured because of lingering limitations in Xcloud's Firefox support, while other cloud gaming services default to Firefox for the better out-of-the-box controller experience.

Backups are single .tar.gz archives containing the full browser profile directory, the launcher script, the .desktop file, the app icon, and a metadata sidecar. Appify keeps up to 10 backups per app, pruning the oldest when the limit is exceeded. Restores wipe the current profile and replace it, then regenerate the launcher and .desktop file with current system paths, which means restores work cleanly even if you have moved things around or changed your setup.

Appify works across distros because it only creates a .pwa_manager file and detects the display server at runtime. There are no distro-specific dependencies in the core path. It is available as a .deb for Debian-based systems and as an AppImage for everything else.

Process Sentry v3 includes a specific exemption for Appify apps. Any browser process whose command line contains ~/.pwa_manager/profiles/ is automatically excluded from throttling, distinguishing Appify apps from regular browser windows without requiring any manual configuration. This is particularly relevant for cloud gaming sessions, which benefit from running at full CPU priority.


KERNEL AUTOTUNE V2 Version 2.0.0 GitHub: https://github.com/bobbycomet/kernel-autotune-V2

What it is for Windows users:

The Linux kernel ships with parameters tuned for maximum compatibility across all possible hardware configurations rather than for performance on your specific machine. This is the sensible default for a project that needs to run on everything from embedded systems to servers, but it means a desktop or gaming PC running a stock kernel is leaving performance on the table.

Kernel Autotune fixes this automatically. It detects your hardware, detects what kind of kernel you are running, and applies the appropriate configuration at boot. You never see any of this happening. Your system just runs better. Memory is managed more efficiently. The network stack performs closer to its actual capability. Storage I/O is scheduled appropriately for whether you have an SSD or an HDD. The CPU governor matches your use case. If you change kernels using XKM, Kernel Autotune reapplies the right configuration to the new kernel automatically.

The technical side:

Kernel Autotune is a shell script that runs as a systemd service. It identifies the running kernel by inspecting the kernel version string, recognizing XanMod, Liquorix, Zen, TKG, CK, Clear, CachyOS, and standard mainline variants. It detects hardware class by checking for battery presence and handheld device identifiers, classifying the system as a desktop, laptop, or handheld device like a Steam Deck or ROG Ally.

Based on this detection, it applies a tailored profile via a sysctl drop-in written to /etc/sysctl.d/99-kernel-autotune.conf. The tuning covers several areas:

Memory management: Zram and Zswap are configured based on total RAM. Swappiness is adjusted for the workload class, with lower values for desktops to keep more data in RAM, and VFS cache pressure and dirty ratios are tuned to balance write-back performance against memory consumption.

Storage: Block devices are detected as SSD or HDD, and the I/O scheduler is set accordingly. SSDs get the none scheduler since they do not benefit from request reordering. HDDs get bfq, which provides fair queuing that improves desktop responsiveness when the disk is under load. The fstrim.timer unit is enabled automatically for SSD maintenance.

Network: BBR TCP congestion control is enabled, replacing the default CUBIC. BBR uses a model of the network path rather than packet loss as a signal, which produces significantly better throughput on modern networks. Buffer sizes are also optimized for high-speed networking.

CPU: The scaling governor is set based on device type and power source. A plugged-in desktop gets the performance or schedutil governor depending on the kernel. A laptop on battery gets PowerSaver or Conservative to preserve charge. The governor's choice is re-evaluated when the power source changes.

Thermal management: On laptops, Transparent Huge Pages are adjusted to reduce the heat generated by large memory page management, which can cause measurable thermal overhead on mobile hardware.

Kernel-specific tuning: XanMod and Liquorix kernels expose additional scheduler and latency parameters that Kernel Autotune configures when it detects those kernels. Standard mainline kernels get a more conservative profile appropriate to their design.

The tool writes a state.json file to /etc/kernel-autotune/ that records the detected kernel type, hardware profile, and the parameters that were applied. Other Griffin tools read this file to understand the current system state without having to re-detect it themselves. The configuration is stored in /etc/kernel-autotune/config.sh and can be edited directly. All settings are fully reversible by editing the config or removing the sysctl drop-in. Kernel Autotune is aware of XKM: when XKM installs a new kernel and updates the shared state, Autotune reapplies its configuration profile without manual intervention.


PROCESS SENTRY V3 Version 3.1.0 GitHub: https://github.com/bobbycomet/Process-Sentry

What it is for Windows users:

On Windows, if a background process started spiking your CPU during a game, you might have caught it in Task Manager, ended it, and moved on. Windows also has some built-in mechanisms for deprioritizing background work when a foreground application is active. Linux has none of that by default. Background processes run at the same priority as your game, your audio server, and your compositor. If something decides to update itself or chew through your disk in the background, you feel it immediately.

Process Sentry watches your running processes continuously, learns which ones are well-behaved and which ones are repeat offenders, and quietly throttles the ones causing problems before they affect whatever you are doing. It never kills anything. It never touches games, audio servers, display compositors, your desktop shell, or your Appify apps. The more you use an application, the more Sentry learns that it is something you care about, and the less likely it is to throttle it unless the system genuinely has no other option. The whole thing runs as a background service and requires no ongoing configuration for the majority of users.

The technical side:

Process Sentry is a Python 3 systemd daemon that uses psutil for process inspection and cgroup v2 for enforcement. Its throttling mechanism is layered. When a process exceeds configured thresholds for CPU usage, I/O throughput, or memory pressure, Sentry first adjusts its scheduling priority via nice(15) and its I/O priority via ionice, moving it into the idle I/O class. It then moves the process into a sentry.slice cgroup with hard CPU quota and I/O weight limits applied via the cgroup v2 hierarchy. If cgroup v2 is not available on the system, Sentry falls back gracefully to nice and ionice only.

The CPU quota calculation is correct by design: the formula is quota_us = (pct / 100) * period_us * cpu_count, which means a 70% quota on a 16-core machine gives the throttled process 70% of a single core's worth of CPU time distributed across the system, rather than naively throttling it to a fraction of total CPU. This was a bug in earlier versions and is fixed in v3.1.0. Memory pressure handling is optional: a memory.high ceiling can be applied to the sentry.slice cgroup, floored at 256 MiB to prevent the slice from becoming so small that any process inside it thrashes constantly.

The learning system is the core of what makes Sentry different from a simple threshold monitor. It maintains a habit score between 0.0 and 1.0 per process name, stored in /var/lib/process-sentry/habits.yaml. The score rises by an up_rate each time a process is throttled, falls by a down_rate each cycle that the process stays within limits, and decays passively over time at a decay_rate applied proportionally to elapsed time. This means the decay rate stays consistent even when the daemon is busy, or the poll interval varies, which was another bug fixed in v3.1.0. Once a process's habit score exceeds the pre_throttle_confidence threshold (default 0.75), it is pre-emptively throttled at the start of each cycle before it even spikes. A secondary predictive trigger also fires early throttling if a process's recent CPU history average exceeds 80% of the current threshold, catching processes that are clearly trending toward a spike before their habit score has had time to build.

The polling interval adapts dynamically using an exponential moving average of system load. The interval ranges from a configurable minimum, as low as 0.5 seconds under heavy load, to a configurable maximum of up to 30 seconds at idle. This means the daemon is responsive when it needs to be and consumes negligible CPU when the system is quiet.

Gaming integration works through multiple mechanisms. Process names matching the gaming_markers configuration list are completely excluded from throttling and trigger a Gamemode request via a D-Bus call to com.feralinteractive.GameMode.RegisterGame using gdbus. This is the correct client API for Gamemode, not starting a second daemon instance as previous versions incorrectly did. When a game is detected, Sentry also suppresses new throttle decisions for a configurable window (default 30 seconds) and raises the CPU threshold by a configurable multiplier (default 1.5x) for the duration. A two-scan debounce prevents rapid toggling if a game briefly disappears from the process list. When games have been absent for two consecutive scans, the Gamemode request is released.

PID reuse is handled correctly: the process class cache is invalidated when a PID is reused by a different process, detected by name change, so a new process cannot inherit the wrong throttle classification from a process that previously occupied that PID.

The configuration file at /etc/process-sentry/config.yaml is fully documented and covers throttle thresholds, learning rates, cgroup parameters, gaming behavior, polling intervals, the EMA smoothing factor, per-mode threshold overrides, and the exclusions list. The exclusions list ships with a broad default set covering IDEs, creative tools, communication apps, browsers, terminals, audio servers, compositors, and system monitors, so most users will not need to add manual exclusions. Appify apps are automatically exempted via the PWA Manager profile path detection. The kill switch at /etc/no-auto-throttle suspends all throttling decisions without stopping the service, which is useful before running benchmarks. Process Sentry v3 runs on any systemd-based Linux system.


XKM: MULTI-KERNEL MANAGER Version 2.0.0 GitHub: https://github.com/bobbycomet/XKM-Multi-Kernel-Manager

What it is for Windows users:

The Linux kernel is the core of the operating system, and different kernel builds are tuned for different priorities. XanMod is a performance-focused kernel with versions tuned to specific CPU instruction set generations. Liquorix is a low-latency kernel aimed at desktop and gaming use. The standard Ubuntu or Debian kernel prioritizes long-term stability and broad hardware compatibility. Switching between these on most Linux systems means learning about PPAs, adding signing keys manually, running apt commands, and hoping the bootloader updates correctly afterward. If you also have DKMS modules like NVIDIA drivers, those need to be rebuilt for the new kernel, which is another manual step that is easy to miss.

XKM gives you a graphical interface that handles all of it. You open the app, browse the available kernels organized by family, check the ones you want, and click install. The tool adds the necessary repositories if they are not already present, installs both the kernel image and headers, handles DKMS rebuilds, updates the bootloader, and cleans up old kernels when you ask it to. You reboot into the new kernel. No commands. No PPA documentation. No wiki pages about kernel signing keys.

The technical side:

XKM reads the system APT package cache directly using Python bindings to the apt library, which means browsing the available kernel list requires no network connection. The package list is current as of the last apt update, and XKM runs apt update before each refresh to ensure the list reflects the current repository state. Browsing is instant.

The tool supports three kernel families. XanMod is presented with a flavor filter that maps to x86-64 microarchitecture levels: v1 runs on any x86-64 CPU, v2 requires SSE4.2 (most hardware from approximately 2008 onwards), v3 requires AVX2 (Intel Haswell and AMD Ryzen and newer), and v4 requires AVX-512 (high-end modern CPUs only). The edge and LTS variants are also available. Liquorix is presented as a single family. Mainline Ubuntu and Debian kernels are listed in the third tab. Each tab shows installed versions, available versions, and which kernel is currently running, with held packages visually distinguished.

Installing a kernel installs both the linux-image and linux-headers packages together. Linux headers are required for DKMS modules, including NVIDIA drivers. XKM handles DKMS rebuilds automatically for the new kernel after installation, so NVIDIA or other DKMS modules do not break silently when you switch kernels. Bootloader updates are handled as part of the installation process.

Kernel pinning is exposed as a GUI operation. Marking a kernel as held calls apt-mark hold on the relevant packages, preventing apt upgrade from replacing it automatically. Held kernels are visually badged in the interface. The unhold operation calls apt-mark unhold. The auto-remove feature removes older installed kernels while keeping the currently running kernel and the most recent one, which prevents the /boot partition from filling up over time while still maintaining a fallback option.

Repository setup for XanMod and Liquorix is handled on first launch when the repositories are not already present. XKM detects the missing repos, prompts you to add them, and handles the PPA addition and signing key import automatically. If you dismiss the prompt, it does not ask again.

Logs of all install, remove, and update operations are written to ~/.config/xanmod-kernel-manager/logs/. The details panel in the interface shows live output during operations. Kernel Autotune detects when XKM has installed a new kernel by watching the shared state file and reapplies its configuration profile to the new kernel without any manual intervention. XKM currently ships as a .deb package, with an AppImage coming.


FAN HUB Beta GitHub: https://github.com/bobbycomet/Fan-Hub

What it is for Windows users:

On Windows, tools like Argus Monitor, FanControl, NZXT CAM, and SpeedFan let you see your system temperatures, read fan speeds in RPM, draw custom fan curves that automatically adjust fan speed as temperatures change, and control RGB lighting across your hardware. These are well-established tools that most PC enthusiasts have used at some point. They work because Windows exposes the necessary hardware interfaces in a relatively consistent way, and software vendors have had years to build against them.

On Linux, the equivalent has historically been a multi-step process involving running sensors-detect to figure out which kernel module handles your motherboard's SuperIO chip, manually loading that module, editing lm-sensors configuration files, and using command-line tools to read temperatures. Fan control on top of that requires either fancontrol (which needs manual calibration and lives entirely in config files) or direct sysfs writes that do not persist across reboots. RGB control has OpenRGB, which is an excellent tool, but requires its own setup. None of this is unified. None of it looks like the Windows tools people are used to.

Fan Hub is the Linux version of those tools. You get a graphical interface with seven tabs covering a live dashboard with temperature gauges and RPM readings, per-fan speed controls with manual sliders and curve assignment, a visual curve editor where you draw your own temperature-to-speed curves by clicking on a graph, RGB control through OpenRGB for any compatible device, AIO cooler control via liquidctl, profile management for saving and switching between configurations, and a settings tab. It is currently in beta, which means it does not yet persist changes as an autostart service, but the functionality for monitoring and control is there and working.

The technical side:

Fan Hub is built with PyQt6 and organizes its hardware access across four backend layers.

The primary backend is the hwmon sysfs interface at /sys/class/hwmon/. Fan Hub maps each hwmon directory at startup, reading fanN_input for current RPM, pwmN for PWM duty cycle (0 to 255), pwmN_enable for control mode (0 for DC, 1 for PWM manual, 2 for PWM auto), tempN_input for temperature in millidegrees Celsius, and associated label and threshold files. Fan paths are stored at discovery time and read directly during the polling loop to avoid path reconstruction overhead. To enable manual fan control, Fan Hub writes 1 to pwmN_enable before writing the duty cycle value, and restores auto control by writing 2 when the application closes, or the user exits a controlled profile. This means fan speeds always return to motherboard management when Fan Hub is not running; nothing is permanently overridden at the firmware level.

NVIDIA GPU temperatures are read via nvidia-smi with the --query-gpu=temperature.gpu flag called each poll cycle, requiring the proprietary driver. AMD GPU temperatures are available through the amdgpu hwmon sysfs interface without ROCm, and via rocm-smi for systems where ROCm is installed. Both paths are checked at startup, and the available one is used.

AIO coolers and USB-connected fan controllers are managed through the liquidctl CLI in JSON output mode, with a plain text fallback for devices that do not support JSON. Supported device families include NZXT Kraken X, Z, and Elite series, Corsair Hydro H60, H100, H115, and H150, Corsair Commander Pro and Commander Core, NZXT Smart Device 2 and Grid+, EVGA CLC, and Aqua Computer devices. Devices are auto-discovered via liquidctl list at startup. These devices appear in the Liquid and AIO tab rather than the main Fan Control tab, since they are controlled through liquidctl rather than directly through sysfs.

RGB control connects to the OpenRGB SDK server over TCP on localhost:6742. Fan Hub uses the openrgb-python SDK when available and falls back to the CLI with server host and port flags. The OpenRGB binary is discovered automatically by checking system PATH, dpkg package output, a list of common directories including ~/Downloads, ~/Applications, ~/.local/bin, ~/bin, ~/Desktop, /opt, and /usr/local/bin, and Flatpak and Snap installs. The AppImage filename does not need to match any specific pattern; any file containing openrgb case-insensitively in the searched directories will be found. Once connected, Fan Hub can control RGB without OpenRGB remaining open as a visible window, since it communicates directly with the server process.

The fan curve engine uses piecewise linear interpolation between control points sorted by temperature. For a target temperature between two points, the speed is calculated as a linear ratio between the speeds at those points. Speed is clamped to the configured minimum and maximum. If a stop-below temperature is configured and the current temperature is below it, the fan is set to zero RPM regardless of the curve. Hysteresis is implemented asymmetrically: the fan responds immediately to temperature increases but requires the temperature to drop by more than half the hysteresis value before decreasing speed. This prevents rapid oscillation when the temperature fluctuates near a curve boundary, which is a common problem with simple threshold-based fan control implementations.

The polling worker runs in a QThread at a configurable interval, default 1000 milliseconds. Each cycle reads all hwmon temperatures, emits sensor data to the UI, computes target fan speeds for any fans with curve assignments, writes the results to sysfs, reads all fan RPMs, reads liquidctl device status, and checks whether any sensor has exceeded the emergency threshold. If the emergency threshold is reached, all fans are immediately set to 100% regardless of their assigned curves.

Required kernel modules for hardware access are nct6775 for most ASUS and Gigabyte boards, it87 for most MSI and ASRock boards, coretemp for Intel CPU package temperature, and i2c-dev for I2C bus access. The installer loads these modules and persists them via /etc/modules-load.d/fanhub.conf. udev rules are written to /etc/udev/rules.d/99-fanhub.rules, granting write access to hwmon sysfs nodes so fan speed writes do not always require root. Separate udev rules grant uaccess to USB devices for liquidctl for Corsair, NZXT, Cooler Master, EVGA, Thermaltake, Aqua Computer, MSI, and ASUS vendor IDs. Profiles are stored as JSON files in ~/.config/fanhub/profiles/ and can be backed up, shared, or edited manually.


WINBRIDGE Version 1.6.0, Early Development No public release yet, development ongoing

What it is for Windows users:

Running Windows applications on Linux through Wine has historically required knowing what Wine is, understanding the difference between Wine prefixes, knowing which Windows runtime libraries an application needs and how to install them through winetricks, figuring out whether to use Proton GE, Wine GE, or Wine Staging, and then troubleshooting whatever breaks afterward. Tools like Bottles and Lutris have made this easier, but they still require significant knowledge to use well, and they each have their own design philosophy that may or may not match what you are trying to do.

WinBridge takes a different approach. Instead of presenting you with a list of configuration options, it presents you with a list of profiles matched to what you are trying to do: Gaming, Modded Games, Productivity, Creative Tools, Streaming Software, Legacy Software, Developer Tools, and specific profiles for things like Vortex and Mod Organizer 2. You pick a profile, point WinBridge at your installer, and it handles the Wine environment, the runtime libraries, DXVK if it is needed, the right Wine build for the workload, and post-installation verification that everything actually worked. The profile system is the key design difference from other tools: rather than making you configure each component, the profile encodes what a given category of software needs and handles it automatically.

The technical side:

WinBridge is a Python and PyQt6 application with a profile-driven architecture that coordinates Wine environment creation, runtime dependency installation, and lifecycle management for Windows applications on Linux.

Profiles specify the preferred runner (Proton GE for games, Wine GE for launchers and mod managers, Wine Staging for creative and development tools, Wine Stable for legacy software), the set of Windows runtime modules to install via winetricks, and an ordered set of lifecycle phases for installation and post-installation. The module resolution system handles conflict detection and dependency expansion before installation begins. Resolution is deterministic: the first-listed module wins when conflicts exist, conflicting later modules are removed with a warning, and dependencies are expanded via breadth-first search. For example, selecting DXVK automatically adds VC Runtime 2022 as a dependency. Known conflicts include DXVK versus WineD3D, VKD3D versus WineD3D, and 32-bit libraries versus the full .NET stack. The resolved module list is shown to the user before any changes are made.

Each installed application gets an isolated Wine prefix in ~/.local/share/winbridge/prefixes/ along with a record in apps.json. Runners are managed separately in ~/.local/share/winbridge/runners/ and are downloaded from GitHub (Proton GE and Wine GE) or use system-installed Wine builds. The tool can auto-discover existing runners by scanning common directories, including Steam's compatibilitytools.d, Lutris's runner directories, Heroic's tools directory, and ProtonUp-Qt's installation directories.

The installation lifecycle is step-based. Steps include init_prefix (wineboot to initialize the prefix), install_modules (winetricks with the resolved verb list), run_exe (executing the Windows installer inside the prefix), fetch_resource (downloading external files like the MO2 Linux installer), register_nxm_handler (registering the nxm:// URI scheme for Nexus Mods), and several verification steps. Post-installation checks run after the installer completes and report results with actionable fix hints if something is wrong. The dry-run mode prints the complete planned operation without making any changes.

The plugin system extends every aspect of WinBridge: profiles, modules, runners, and system checks can all be added by community plugins. Plugins are Python files dropped into ~/.local/share/winbridge/plugins/. They are processed through a three-layer security model before execution. The first layer is an AST static analysis pass that runs on every plugin regardless of trust level, blocking calls to os.system, os.popen, shell-mode subprocess invocations, exec, eval, import, compile, and shutil.rmtree, and blocking dangerous string literals including rm -rf, sudo, dd if=, mkfs, and redirections to /dev/. The second layer is the execution context tier system: untrusted and community plugins run sandboxed (via bubblewrap if available for full Linux namespace isolation, or via a minimal subprocess with stripped environment as a fallback), Wine and winetricks invocations run in a controlled context validated against an executable allowlist, and prefix creation and filesystem operations run natively because they require real filesystem access. The third layer is a manual trust sidecar: users can place a .trusted file next to a plugin to grant it full in-process execution with access to the register() hook, but this file must be created manually by the user and cannot be self-granted by the plugin.

NXM URL handling for Nexus Mods is implemented by writing a handler shell script and a .desktop file during Vortex or MO2 installation, then registering it via xdg-mime. When a Mod Manager Download button is clicked on the Nexus Mods website, the browser dispatches the nxm:// URL to WinBridge, which routes it to the running mod manager inside its Wine prefix. Snapshots are versioned .tar.gz archives per application stored in ~/.local/share/winbridge/snapshots/, capped at five per app with automatic pruning. Restoration uses safe_tarextract() with path traversal prevention. Base support targets KDE, Ubuntu, and Kubuntu, with distro plugins extending compatibility to other systems through the PLUGIN_DISTRO_OVERRIDES mechanism.


Tools in Active Development

The following tools are part of Griffin but do not yet have public releases. They are described here because they are referenced by the tools above and are necessary context for understanding how the full system fits together.

Game Tune Hub is where Steam wrapping, Gamemode, Gamescope, and Mangohud configuration live. It wraps the Steam executable so the resulting process tree carries the gamemoded signature that Process Sentry detects at runtime. It backs up the original Steam executable before wrapping, so the change is always reversible. It also serves as the GUI configuration surface for both Process Sentry and Kernel Autotune settings, replacing the need to edit config files directly for the majority of users.

Griffin Hub houses Controller Hub, CPU Hub, GPU Hub, and WiFi Hub in a single application. GPU Hub includes the hardware swap feature: when a user switches to a GPU from a different vendor, clicking the swap button safely reverts to base drivers and removes vendor-specific extras (CUDA, NVENC, AMD ROCm) so the new hardware can be installed cleanly without leftover conflicts. GPU Hub also handles the detection and installation of those extras based on detected hardware. CPU Hub provides governor control as an override on top of Kernel Autotune's baseline. WiFi Hub handles Realtek and Broadcom driver issues via a dedicated GUI.

Grix is the system health and support layer. It handles PipeWire audio fixes, drive health monitoring via SMART data, capacity warnings with plain-language steps, and a learn function that explains what is happening and why. It surfaces issues that dedicated tools do not cover and either walks you through a fix or asks for approval to handle it automatically. Everything Grix does is logged and reversible.

Griffin Persona is the workflow setup tool, formerly called Postinstaller. You select workflow profiles such as Gaming, Streaming, Productivity, Audio Production, VTubing, or General Use, and it installs the corresponding application bundles. It also detects your GPU hardware and can install the appropriate driver stack and compute extras (NVENC, CUDA, ROCm) as part of the workflow setup. It is not tied to a fresh install or first boot; you can run it at any time to set up or expand your workflow.

Griffin Updater manages installs and updates for the full Griffin tool suite. It checks each tool's GitHub repository for new releases, notifies you when updates are available, and handles installation without requiring the terminal. For tools available in both AppImage and Deb formats, you choose your preferred format once, and the updater remembers it, showing only that option going forward. For first-time installs, the updater handles the full installation of any tool with a single click.


Scope and Maintainability

Griffin's primary target is Debian and Ubuntu-based systems, and this is worth explaining directly rather than treating it as a footnote. The most common failure mode for open source system tooling is overreach: trying to handle every distribution, every init system, every display server combination, and every package manager simultaneously. The result is usually code that works poorly everywhere and is nearly impossible to maintain as upstreams change.

Griffin avoids this by being deliberate about scope. Kernel Autotune, XKM, Fan Hub, and the Hub tools are built and tested against Debian and Ubuntu-based systems. The kernel parameter tuning in Autotune references specific sysfs paths and kernel features that need to be verified against known configurations. Fan Hub's module loading and udev rules are tested against known chipsets. XKM's repository management is built around apt.

The tools that work more broadly, Appify, WinBridge via its distro plugin system, and Sentry v3, are designed that way by nature. Appify creates a .pwa_manager file and detects the display server at runtime, so it does not have distro-specific dependencies in its core path. Sentry v3 uses systemd for service management and psutil for process inspection, both of which work across most modern Linux distributions. WinBridge's distro plugin architecture deliberately separates the base KDE and Ubuntu support from the extension layer, so other distributions can be supported through plugins without requiring changes to the core.

Users on other distributions are welcome to use the tools that fit their system. The ones with broader compatibility are documented as such in each section above.


Get Involved

Griffin is shaped by the people using it. Every tool described in this post has been influenced by feedback from people who are actually switching from Windows to Linux and running into the problems these tools are designed to solve. If something here sounds useful, or if you have hit a problem on Linux that none of this seems to address, Discord is the fastest way to follow along, try early builds, and give feedback that directly changes what gets built next.

Discord: https://discord.gg/7fEt5W7DPh | Patreon (early builds and development support): https://www.patreon.com/c/BobbyComet | Ko-fi (one-time support): https://ko-fi.com/bobby60908

Kernel autotune version 2.2.0 is now out

Kernel Autotune v2.2.0 TLDR: Makes your system more predictable by automatically tuning your Linux kernel, memory, CPU, storage, and network...