Skip to main content

Overview

ShojiWM is configured entirely from TypeScript/TSX. Your config is a normal TypeScript module that imports from shoji_wm and talks to the compositor through a single root object: COMPOSITOR.

import {COMPOSITOR, ManagedWindow, ClientWindow, WindowBorder} from 'shoji_wm';

// Launch a terminal with Super+T
COMPOSITOR.key.bind('terminal', 'Super+T', () => {
COMPOSITOR.process.spawn({command: ['kitty']});
});

// Decide how every window is decorated
COMPOSITOR.window.composition = (window) => (
<ManagedWindow rect={window.position} zIndex={1}>
<WindowBorder style={{borderRadius: 10, border: {px: 2, color: '#d7ba7d'}}}>
<ClientWindow />
</WindowBorder>
</ManagedWindow>
);
tip

Your config is read from ~/.config/shojiwm/ by default (the entry point is ~/.config/shojiwm/src/index.tsx) — that's the file to edit. The examples throughout this section are drawn from the default config (packages/config/src/index.tsx). It is the best end-to-end reference once you understand the individual pieces below. For a tour of what it does out of the box — keybindings, window behavior, and more — see Default config.

The COMPOSITOR object

COMPOSITOR groups every configurable area under a named field. Each gets its own page in this section:

FieldWhat it controlsPage
event, onEnable, onDisableLifecycle hooks and the window/input/output event busLifecycle & Events
outputMonitor resolution, scale, position, mirroringOutputs
inputKeyboard, pointer, and touchpad device settingsInput devices
key, pointerKeyboard shortcuts and pointer modifiersKeybindings & Pointer
process, envSpawning programs and environment variablesProcesses & Environment
windowPer-window decoration (the composition function)Window composition
effectGPU effects: background blur, per-window/layer/popup shadersEffects
debugDebug overlays such as the FPS counterLifecycle & Events

Building blocks used inside the composition function have their own pages too:

  • SSD Components<Box/>, <Label/>, <Button/>, <AppIcon/>, <Image/>, <ShaderEffect/>, <WindowBorder/>, <ManagedWindow/>, <ClientWindow/>, and the full style reference.
  • State & Signals — the reactive model behind automatic updates.
  • Animations — driving smooth transitions.

Mental model

  1. The compositor core (Rust) sends your config a live, reactive view of each window, output, and input device.
  2. Your config reads those values, registers callbacks, and (for windows) returns a small TSX tree describing the decoration.
  3. When any value your code read changes, only the affected part is re-evaluated. This is the signal system — see State & Signals.

If you have not yet, read the architecture overview for how the two halves fit together.