# Hyprland Plugin System: Architecture, Loading Mechanism, and Runtime Safety

> Explore the Hyprland plugin system an advanced dynamic shared-library architecture. Learn how it extends the Wayland compositor at runtime with C entry points and fault-isolated hooks.

- Repository: [Hypr Development/Hyprland](https://github.com/hyprwm/Hyprland)
- Tags: architecture
- Published: 2026-07-23

---

**The Hyprland plugin system is a dynamic shared-library infrastructure that allows third-party developers to extend the Wayland compositor at runtime through C-style entry points, registration macros, and fault-isolated event hooks.**

The Hyprland plugin system enables modular extensions without modifying core compositor code. Located in the `src/plugins` directory of the hyprwm/Hyprland repository, this architecture supports runtime loading of `.so` files, integration of custom window decorations and hyprctl commands, and crash-resistant execution via advanced fault isolation.

## Core Components and File Structure

The implementation spans three primary layers in `src/plugins/`:

- **Plugin System** ([`PluginSystem.hpp`](https://github.com/hyprwm/Hyprland/blob/main/PluginSystem.hpp) and [`PluginSystem.cpp`](https://github.com/hyprwm/Hyprland/blob/main/PluginSystem.cpp)): Manages `dlopen`/`dlclose` operations, lifecycle tracking, and fault recovery through the `CPlugin` and `CPluginSystem` classes.
- **Plugin API** ([`PluginAPI.hpp`](https://github.com/hyprwm/Hyprland/blob/main/PluginAPI.hpp) and [`PluginAPI.cpp`](https://github.com/hyprwm/Hyprland/blob/main/PluginAPI.cpp)): Exposes registration functions and helper macros (e.g., `PLUGIN_REGISTER_DECORATION`) via the `CPluginAPI` class.
- **Hook System** ([`HookSystem.hpp`](https://github.com/hyprwm/Hyprland/blob/main/HookSystem.hpp) and [`HookSystem.cpp`](https://github.com/hyprwm/Hyprland/blob/main/HookSystem.cpp)): Provides event interception capabilities through `HOOK_REGISTER` macros and the `CHookSystem` dispatcher.

## Discovery and Dynamic Loading

Hyprland reads the `plugins` configuration entry to determine which shared libraries to load. The `CPluginSystem::loadPlugin()` method initiates the process by creating a `CPromise<CPlugin*>` that handles asynchronous loading.

The internal `loadPluginInternal()` function resolves the library path and attempts to open the `.so` file using `dlopen`, storing the resulting handle in the `m_handle` field of the `CPlugin` instance. It validates that the library exports two mandatory symbols: `plugin_init` and `plugin_deinit`. If either entry point is missing or the `dlopen` call fails, the promise resolves with an error string and the library is rejected before initialization begins.

## Initialization and API Registration

Upon successful loading, Hyprland invokes the exported `plugin_init()` function, passing a pointer to the global `CPluginAPI` object. This pointer serves as the primary interface for registering custom functionality with the compositor.

```cpp
extern "C" void plugin_init(CPluginAPI* api) {
    // Register a custom window decoration
    api->registerWindowDecoration("mydecoration", []() {
        return new MyDecoration();
    });
    
    // Register a hyprctl command
    api->registerHyprctlCommand("mycmd", "Shows plugin info", [](CHyprCtlCommand* cmd) {
        hyprlog::info("Plugin command executed");
        return true;
    });
}

```

Behind these calls, the `PLUGIN_REGISTER_DECORATION`, `PLUGIN_REGISTER_HYPRCTL_COMMAND`, and `PLUGIN_REGISTER_CONFIG_VALUE` macros push function pointers into vectors stored in the owning `CPlugin` instance—specifically `m_registeredDecorations`, `m_registeredHyprctlCommands`, and analogous containers for config values.

## Runtime Hook System and Event Interception

The Hook System allows plugins to intercept internal compositor events without modifying core source code. Defined in [`src/plugins/HookSystem.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/plugins/HookSystem.hpp), it exposes identifiers such as `HOOK_WINDOW_CREATED` and `HOOK_LAYOUT_CHANGED`.

Plugins register callbacks using the `HOOK_REGISTER` macro or direct API calls:

```cpp
extern "C" void plugin_init(CPluginAPI* api) {
    api->registerHook(HOOK_WINDOW_CREATED, [](CWindow* w) {
        hyprlog::debug("Window {} created, plugin reacting.", w->m_szTitle);
    });
}

```

When internal events fire, `CHookSystem` dispatches these callbacks synchronously, allowing plugins to react to window creation, layout changes, and other lifecycle events in real time.

## Unloading and Resource Cleanup

When a user disables a plugin or Hyprland shuts down, `CPluginSystem::unloadPlugin()` invokes the exported `plugin_deinit()` function. This triggers the cleanup of all callbacks and resources stored in the `CPlugin` object, followed by `dlclose` to release the shared library from memory and invalidate the `m_handle`.

## Safety Mechanisms and Fault Isolation

The Hyprland plugin system implements multiple safeguards to prevent unstable plugins from crashing the compositor:

- **Fault Recovery**: Each plugin call is wrapped with `setjmp/longjmp` using a `jmp_buf` stored in `m_pluginFaultJumpBuf`. If a plugin throws an unrecoverable C++ exception or segfaults, the system jumps back to the saved context rather than propagating the error to the main process.
- **Permission Management**: The `DynamicPermissionManager` enforces capability restrictions. The boolean flag `m_allowConfigVars` specifically controls whether a plugin may register custom configuration variables, preventing unauthorized configuration pollution.
- **Memory Safety**: All plugin-related objects use Hyprutils smart pointers (`UP<>`, `WP<>`, `SP<>`) for automatic reference counting and deterministic lifetime management.

## Summary

- The **Hyprland plugin system** dynamically loads `.so` files via `dlopen` using the `CPluginSystem` class defined in [`src/plugins/PluginSystem.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/plugins/PluginSystem.cpp).
- **Entry points** `plugin_init` and `plugin_deinit` are mandatory; `plugin_init` receives a `CPluginAPI*` pointer for registering decorations, commands, and config values.
- **Registration macros** like `PLUGIN_REGISTER_DECORATION` push callbacks into `CPlugin` member vectors such as `m_registeredDecorations` and `m_registeredHyprctlCommands`.
- The **Hook System** ([`src/plugins/HookSystem.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/plugins/HookSystem.cpp)) enables event interception through identifiers like `HOOK_WINDOW_CREATED`.
- **Fault isolation** via `setjmp/longjmp` and `m_pluginFaultJumpBuf` prevents plugin crashes from destabilizing the main compositor process.

## Frequently Asked Questions

### How do I load a plugin in Hyprland?

Add the absolute path to your compiled `.so` file in the `plugins` configuration entry within your Hyprland config. When the compositor starts or reloads, `CPluginSystem::loadPlugin()` automatically validates the library and invokes `plugin_init()` if the required entry points are present.

### What programming language are Hyprland plugins written in?

Plugins must be compiled as C++ shared libraries that export C-linkage symbols using `extern "C"`. The API uses C-style callbacks to ensure Application Binary Interface (ABI) stability across different compiler versions and toolchains.

### Can a malfunctioning plugin crash the entire compositor?

No. The system wraps every plugin call with `setjmp/longjmp` using the `m_pluginFaultJumpBuf` buffer. If a plugin crashes or throws an uncaught exception, Hyprland catches the fault, prevents the crash from propagating, and safely unloads the offending plugin while keeping the compositor running.

### Where are the official Hyprland plugin API headers located?

The public API definitions reside in [`src/plugins/PluginAPI.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/plugins/PluginAPI.hpp), loading logic is implemented in [`src/plugins/PluginSystem.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/plugins/PluginSystem.hpp) and `.cpp`, and hook definitions are found in [`src/plugins/HookSystem.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/plugins/HookSystem.hpp). These files are maintained in the official hyprwm/Hyprland repository.