Extend your desktop

Plugins, ready to explore.

Explore real headless captures of every available plugin, alongside shipped defaults, optional native plugins, and the core modules they build on.

Shipped defaults

Built-in plugins

These ship as shared libraries and load automatically after config.lua when their build options are enabled. The plugin manager reports them as builtin = true. Safe mode disables their automatic loading.

Shady headless capture of window-motion: Wobble during a window drag
Headless captureWobble during a window drag
Built-in · Auto-loaded

window-motion

Wobble and tilt for spatial windows, driven through the public motion API.

View source ↗
Shady headless capture of obj-loader: Loaded OBJ environment geometry
Headless captureLoaded OBJ environment geometry
Built-in · Auto-loaded

obj-loader

Loads OBJ environments, including authored collision geometry.

View source ↗

Load what you need

External plugins

Optional native plugins loaded explicitly through shady.plugins.load(). All entries below are repository examples, not a third-party directory. Most are built by ./tools/build.sh, but none are auto-loaded or installed by default.

Shady headless capture of afterglow: Procedural sky and sea
Headless captureProcedural sky and sea
External · Built by default

afterglow

A camera-aware sky and sea, four times of day, and sinking close animations.

Requires spatial + close-animation. Super+T cycles the hour.

shady.plugins.load("afterglow")View source ↗
Shady headless capture of water-windows: Animated liquid window surfaces
Headless captureAnimated liquid window surfaces
External · Built by default

water-windows

Animated liquid surfaces on live windows.

Requires spatial. Super+W toggles the effect.

shady.plugins.load("water-windows")View source ↗
Shady headless capture of focus-depth: Focused window forward, background windows in depth
Headless captureFocused window forward, background windows in depth
External · Built by default

focus-depth

Moves focused and background windows through depth while preserving screen-space placement.

Requires spatial.

shady.plugins.load("focus-depth")View source ↗
Shady headless capture of spatial-overview: Three windows in the 3D overview
Headless captureThree windows in the 3D overview
External · Built by default

spatial-overview

A native 3D window overview that restores the original layout when closed.

Requires spatial. Avoid combining with other position writers.

shady.plugins.load("spatial-overview")View source ↗
Shady headless capture of magnetic-windows: Spring-docked window arrangement
Headless captureSpring-docked window arrangement
External · Built by default

magnetic-windows

Spring-docks nearby windows into spatial structures, with ABI v2 state migration.

Requires spatial. Super+M toggles docking.

shady.plugins.load("magnetic-windows")View source ↗
Shady headless capture of window-constellation: Windows orbiting a focused anchor
Headless captureWindows orbiting a focused anchor
External · Built by default

window-constellation

Orbits windows around the focused window and spring-restores their original layout.

Requires spatial. Super+C toggles the constellation.

shady.plugins.load("window-constellation")View source ↗
Shady headless capture of window-portal: Live window texture through a portal
Headless captureLive window texture through a portal
External · Built by default

window-portal

A refractive circular portal into another live Wayland window.

Requires spatial. Super+P toggles the portal.

shady.plugins.load("window-portal")View source ↗
Shady headless capture of black-hole: Black hole mid-animation
Headless captureBlack hole mid-animation
External · Built by default

black-hole

Swallows workspace windows into a black hole and releases them through a white hole.

Requires spatial. Super+H toggles the effect.

shady.plugins.load("black-hole")View source ↗
Shady headless capture of frozen-window: Frost-covered windows on a frozen workspace
Headless captureFrost-covered windows on a frozen workspace
External · Built by default

frozen-window

Frost crystallises across a window and melts away again, without touching its layout or input.

Requires spatial. Super+Z freezes the focused window; Super+Shift+Z the workspace.

shady.plugins.load("frozen-window")View source ↗
Shady headless capture of astral-loom: Procedural sky and spatial window representations
Headless captureProcedural sky and spatial window representations
External · Built by default

astral-loom

Procedural sky, glass window representations, and animated spatial layouts.

Requires spatial. Includes shaders; the associated rice is archived.

shady.plugins.load("astral-loom")View source ↗
Shady headless capture of fps-cube: Folded cube window bodies in FPS mode
Headless captureFolded cube window bodies in FPS mode
External · Built by default

fps-cube

Cube-shaped window bodies for FPS interaction.

Requires fps. Choose one FPS representation plugin at a time.

shady.plugins.load("fps-cube")View source ↗
Shady headless capture of fps-squash: Squash window bodies in FPS mode
Headless captureSquash window bodies in FPS mode
External · Built by default

fps-squash

Animated squash representations for FPS window bodies.

Requires fps. Choose one FPS representation plugin at a time.

shady.plugins.load("fps-squash")View source ↗
Shady headless capture of fps-jelly: Springy jelly window bodies in FPS mode
Headless captureSpringy jelly window bodies in FPS mode
External · Built by default

fps-jelly

Springy jelly window bodies for FPS interaction.

Requires fps. Choose one FPS representation plugin at a time.

shady.plugins.load("fps-jelly")View source ↗
Shady headless capture of fps-folded-paper: Folded-paper window bodies in FPS mode
Headless captureFolded-paper window bodies in FPS mode
External · Built by default

fps-folded-paper

Folded-paper mesh window bodies with convex collision geometry.

Requires fps. Choose one FPS representation plugin at a time.

shady.plugins.load("fps-folded-paper")View source ↗
Shady headless capture of fps-origami: Origami window bodies in FPS mode
Headless captureOrigami window bodies in FPS mode
External · Built by default

fps-origami

Spring-driven origami meshes with compound collision bodies.

Requires fps. Choose one FPS representation plugin at a time.

shady.plugins.load("fps-origami")View source ↗
Shady headless capture of border-accent: Magenta border override on the focused window
Headless captureMagenta border override on the focused window
External · Built by default

border-accent

Toggles a per-window border accent on the focused window.

Super+B toggles the accent.

shady.plugins.load("border-accent")View source ↗
Shady headless capture of close-slide-fade: Slide-and-fade close animation in progress
Headless captureSlide-and-fade close animation in progress
External · Built by default

close-slide-fade

Replaces the default crumple close animation with a slide and fade.

Requires spatial + close-animation. Choose one close-effect plugin.

shady.plugins.load("close-slide-fade")View source ↗
Shady headless capture of close-burn: Burn close animation in progress
Headless captureBurn close animation in progress
External · Built by default

close-burn

Adds a shader-driven burn effect to closing windows.

Requires spatial + close-animation. Choose one close-effect plugin.

shady.plugins.load("close-burn")View source ↗
Shady headless capture of shader-overlay: Fullscreen shader overlay
Headless captureFullscreen shader overlay
External · Built by default

shader-overlay

A fullscreen animated shader overlay using host-managed render hooks.

Includes external shader files.

shady.plugins.load("shader-overlay")View source ↗
Shady headless capture of orbit-layout: Focused window with surrounding satellites
Headless captureFocused window with surrounding satellites
External · Build explicitly

orbit-layout

Places the focused window in a primary slot with surrounding satellite windows.

Requires spatial. Build explicitly.

shady.plugins.load("orbit-layout")View source ↗
Shady headless capture of hello: Lifecycle example with actual plugin logs; no visual effect
Headless captureLifecycle example with actual plugin logs; no visual effect
External · Build explicitly

hello

A minimal native plugin example for learning the entry and lifecycle APIs.

Build explicitly. Module name: hello-plugin.

shady.plugins.load("hello")View source ↗
Shady headless capture of counter: Stateful example with actual plugin logs; no visual effect
Headless captureStateful example with actual plugin logs; no visual effect
External · Build explicitly

counter

A stateful example for testing ABI v2 reload and state migration.

Build explicitly. Module name: counter-plugin.

shady.plugins.load("counter")View source ↗

Compositor foundation

Core built-in modules

Compiled into the compositor and selected with shady.module() or shady.modules(). Optional modules depend on your Meson build options; these are not shared-library plugins.

Core module

desktop-protocols

Desktop Wayland protocol integration.

Core module

workspace

Named workspaces, window membership, and visibility.

Core module

spatial

Shared 3D world, camera, and window depth.

Core module

physics

Gravity, velocity, and spatial collisions.

Core module

fps

First-person capture, grabbing, and expanded window bodies.

Core module

close-animation

Per-window close animation lifecycle.

Core module

scene-effects

Scene rendering effects.

Core module

lua

Runtime scripting, events, and key bindings.

Try a plugin

Build, then load in config.lua.

Add the load call to the config you launch with. Names resolve to libshady-plugin-<name>.so, including in the executable's build directory. Loading new plugins happens at startup; runtime Lua supports inspection, reload, and eligible unloads.

terminal
# From the repository root
nix develop
./tools/build.sh

# Examples marked "Build explicitly"
ninja -C build libshady-plugin-orbit-layout.so

# Keep shader assets available to shader-based plugins
export SHADY_ROOT="$PWD"
./build/shady -c examples/config.lua
config.lua
-- config.lua — load before module dependency resolution
shady.plugins.load("water-windows")

-- Optional: add a directory for your own plugins
shady.plugins.path("~/.local/share/shady/plugins")

-- Shipped defaults can be disabled here
-- shady.plugins.disable("obj-loader")