# How the Spacing Scale System Works in Omarchy Shell Themes

> Learn how Omarchy shell themes use a unified spacing scale for consistent design. Discover global multipliers, font-relative scaling, and per-token overrides for precise control.

- Repository: [37signals/omarchy](https://github.com/basecamp/omarchy)
- Tags: deep-dive
- Published: 2026-08-28

---

**Omarchy shell themes rely on a unified spacing scale defined in [`shell.toml`](https://github.com/basecamp/omarchy/blob/main/shell.toml) that multiplies all semantic spacing tokens globally, with optional font-relative scaling and per-token overrides for precise control.**

The Omarchy desktop shell from Basecamp uses a sophisticated spacing architecture to maintain visual consistency across its QML-based interface. Rather than hardcoding pixel values throughout the codebase, the system derives all layout measurements from a single configurable **spacing scale** with semantic token overrides.

## Understanding the Core Spacing Scale

At the heart of Omarchy's layout system lies the `[spacing]` table within each theme's [`shell.toml`](https://github.com/basecamp/omarchy/blob/main/shell.toml) configuration file. This table contains a `scale` factor that defaults to `1.0` and acts as a global multiplier for every spacing-related measurement in the shell.

When you modify the scale value, it proportionally adjusts **shared margins, gaps, padding, control sizes, and panel dimensions** throughout the entire interface. Increasing the scale to `1.15` adds breathing room to buttons, separators, and panel layouts, while lowering it creates a tighter, more compact visual density. According to the Omarchy source code in [`docs/omarchy-shell.md`](https://github.com/basecamp/omarchy/blob/main/docs/omarchy-shell.md) (lines 68-73), this single parameter propagates to all UI elements that reference the spacing system.

## Font-Relative Scaling Behavior

By default, Omarchy couples spacing with typography through the `scale-with-font` property. When set to `true` (the default), the spacing scale automatically follows changes to `[font] base-size` in the same configuration file.

This means increasing the base font size automatically enlarges button paddings, popup widths, row heights, and panel padding proportionally. The system maintains visual harmony between text and surrounding whitespace without manual recalculation. You can disable this behavior by setting `scale-with-font = false` if you need spacing to remain constant regardless of font changes.

## Semantic Spacing Tokens and Overrides

Individual spacing values are exposed through the `Style.spacing.*` namespace in QML. Key tokens include:

- `Style.spacing.controlPaddingX` — Horizontal padding inside buttons and controls
- `Style.spacing.controlPaddingY` — Vertical padding inside buttons and controls
- `Style.spacing.rowGap` — Space between list items or table rows
- `Style.spacing.panelGap` — Distance between adjacent panels or sections

While these tokens derive their values from the scaled base calculation, themes can **override any token directly** within the `[spacing]` table. As documented in [`docs/omarchy-shell.md`](https://github.com/basecamp/omarchy/blob/main/docs/omarchy-shell.md) (lines 96-105), this allows surgical adjustments without disrupting the global scale. For example, you might maintain a large global scale for general spacing while keeping button padding compact for a denser toolbar appearance.

## Implementing Spacing in QML Components

QML components throughout `shell/plugins/**/*.qml` (such as `BarWidget.qml` and `ReminderFlow.qml`) consume spacing values through the **Style singleton**. Always reference semantic tokens rather than raw pixel numbers to ensure your components respect the user's theme settings.

When you must use a specific pixel dimension that still respects the scaling system, call `Style.space(px)`. This function preserves the original pixel value at scale `1.0` while applying the current scale multiplier, ensuring your component scales appropriately with the theme.

```qml
// Preferred: Use semantic tokens
Item {
    padding: Style.spacing.controlPaddingX
    spacing: Style.spacing.rowGap
}

// When fixed proportions are needed
Rectangle {
    width: Style.space(120)   // 120px at scale 1.0, 138px at scale 1.15
    height: Style.space(32)
}

```

## Practical Configuration Examples

Create a roomier interface by adjusting your theme's [`shell.toml`](https://github.com/basecamp/omarchy/blob/main/shell.toml):

```toml
[spacing]
scale = 1.15          # 15% larger spacing globally

scale-with-font = true

# Optional surgical overrides

panel-padding = 22
row-gap = 10

```

For a compact, information-dense layout suitable for smaller displays:

```toml
[spacing]
scale = 0.90          # Reduce spacing by 10%

scale-with-font = false  # Keep spacing tight even with larger fonts

# Tighten specific controls without affecting global gaps

control-padding-x = 6
control-padding-y = 4

```

## Summary

- The `[spacing]` table in [`shell.toml`](https://github.com/basecamp/omarchy/blob/main/shell.toml) controls global visual density through a single `scale` multiplier (default `1.0`).
- **Font-relative scaling** (`scale-with-font`) automatically adjusts spacing when you change the base font size, maintaining proportional relationships.
- **Semantic tokens** like `Style.spacing.panelGap` provide consistent values across QML components located in `shell/plugins/`.
- **Token overrides** allow specific values to deviate from the global scale for precise component tuning.
- Use `Style.space(px)` in QML when you need dimension values that scale with the theme but originate from fixed pixel baselines.

## Frequently Asked Questions

### How do I increase spacing globally in an Omarchy theme?

Add a `scale` value greater than `1.0` to the `[spacing]` table in your theme's [`shell.toml`](https://github.com/basecamp/omarchy/blob/main/shell.toml). For example, `scale = 1.2` increases all margins, paddings, and gaps by 20%. This change immediately affects every component referencing `Style.spacing.*` without modifying individual QML files.

### What is the difference between Style.spacing tokens and Style.space()?

**`Style.spacing.*`** provides semantic, theme-defined values (like `controlPaddingX` or `rowGap`) that scale automatically. **`Style.space(px)`** is a function that converts a specific pixel value at scale `1.0` to the current scaled equivalent—use it when you need a precise dimension (like a 120px wide button) that should still grow or shrink with the theme.

### Does changing the font size affect spacing automatically?

Yes, if `scale-with-font` remains set to `true` (the default). When you increase `[font] base-size`, the spacing scale increases proportionally, ensuring buttons don't become cramped and panels maintain appropriate internal padding relative to their text content.

### Can I override specific spacing values without changing the global scale?

Absolutely. Within the `[spacing]` table, define explicit values for specific tokens like `panel-padding = 22` or `row-gap = 10`. According to the Omarchy documentation, these direct assignments bypass the scale calculation for those specific properties while leaving the global multiplier intact for all other spacing tokens.