Skip to content

Configuration reference

All configuration options with types, defaults, and examples.

Usage

Pass options to configure() before calling start():

spoon.Shoji:configure({
gap_outer = 16,
default_layout = "bsp",
})
spoon.Shoji:start()

Options can also be changed after Shoji starts. Call retile() to apply:

spoon.Shoji:configure({ gap_inner = 12 })
spoon.Shoji:retile()

Layout options

default_layout

Layout assigned to new macOS Spaces.

PropertyValue
Typestring
Default"tall"

Must be a layout name present in enabled_layouts.

default_layout = "bsp"

enabled_layouts

Layouts available when cycling with cycle_layout action.

PropertyValue
Typestring[]
Default{ "tall", "wide", "fullscreen", "bsp" }
Min length1

Available built-in layouts: tall, wide, fullscreen, bsp, grid, column, floating.

enabled_layouts = { "tall", "wide", "bsp", "grid" }

main_ratio

Ratio of the main area. Applies to layouts with a main/secondary split.

PropertyValue
Typenumber
Default0.5
Range0.1 to 0.9

At 0.5, main and secondary areas split equally. Higher values give more space to the main area.

main_ratio = 0.6

nmaster

Number of windows in the main area.

PropertyValue
Typenumber
Default1
Min1
nmaster = 2

Gap options

gap_outer

Space between windows and screen edges.

PropertyValue
Typenumber
Default0
Unitpixels
Min0
gap_outer = 16

gap_inner

Space between adjacent windows.

PropertyValue
Typenumber
Default0
Unitpixels
Min0
gap_inner = 4

Filtering options

filter_mode

How filter_apps is interpreted.

PropertyValue
Typestring
Default"blocklist"
Values"blocklist", "allowlist"
  • "blocklist": tile all windows except apps in filter_apps
  • "allowlist": tile only apps in filter_apps (requires non-empty list)
filter_mode = "blocklist"

filter_apps

App bundle IDs affected by filter_mode.

PropertyValue
Typestring[]
Default{}

To find an app’s bundle ID: hs.application.frontmostApplication():bundleID()

filter_apps = {
"com.apple.finder",
"com.apple.Preview",
"com.apple.systempreferences",
}

min_width

Minimum window width for tiling. Windows narrower than this are excluded.

PropertyValue
Typenumber
Default0 (disabled)
Unitpixels
Min0
min_width = 400

min_height

Minimum window height for tiling. Windows shorter than this are excluded.

PropertyValue
Typenumber
Default0 (disabled)
Unitpixels
Min0
min_height = 300

Alert options

show_layout_alerts

Display on-screen alerts when the layout changes.

PropertyValue
Typeboolean
Defaulttrue
show_layout_alerts = false

show_layout_icon

Display layout icon in on-screen alerts.

PropertyValue
Typeboolean
Defaulttrue

Only applies when show_layout_alerts is true.

show_layout_icon = false

alert_duration

How long layout alerts remain visible.

PropertyValue
Typenumber
Default0.5
Unitseconds
Min0
alert_duration = 1.0

Drag-swap options

Reorder windows by dragging them over each other.

drag_swap

Enable drag-to-swap window reordering.

PropertyValue
Typeboolean
Defaultfalse
drag_swap = true

drag_min_distance

Minimum drag distance before a swap triggers.

PropertyValue
Typenumber
Default40
Unitpixels
Min0

Lower values make swaps trigger more easily.

drag_min_distance = 30

drag_swap_sensitivity

How soon a swap triggers when entering another window’s area.

PropertyValue
Typenumber
Default0
Range0 to 1

At 0, the dragged window must reach the target’s center. Higher values trigger swaps sooner.

drag_swap_sensitivity = 0.3

drag_enabled_layouts

Layouts where drag-swap is active.

PropertyValue
Typestring[]
Default{ "tall" }

Cannot include "floating".

drag_enabled_layouts = { "tall", "wide", "bsp" }

Advanced options

strict_validation

Fail on invalid config instead of using defaults.

PropertyValue
Typeboolean
Defaulttrue

When false, invalid values are replaced with defaults and a warning is logged.

strict_validation = false

layouts

Custom layout implementations.

PropertyValue
TypeLayout[]
Defaultnil

See Custom layouts.

layouts = { require("my_custom_layout") }

hooks

Callbacks for lifecycle and window events.

PropertyValue
Typetable<HookType, function | function[]>
Defaultnil

See Hooks reference for available hooks.

hooks = {
after_tile = function(spaceID)
print("Tiled space: " .. spaceID)
end,
layout_changed = function(spaceID, layout, prev)
print("Layout: " .. (prev or "none") .. " -> " .. layout)
end,
}

retile_on_focus

Retile when window focus changes.

PropertyValue
Typeboolean
Defaultfalse

Useful for magnifier-style layouts where the focused window gets more space.

retile_on_focus = true