# Omarchy Typography Scale: How the Rem-Based System Works in Themes

> Discover how Omarchy themes manage typography using a rem-based scale. Learn how base-size and semantic tokens ensure proportional scaling for your UI.

- Repository: [Omacom/omarchy](https://github.com/omacom/omarchy)
- Tags: how-to-guide
- Published: 2026-08-30

---

**Omarchy implements a rem-style typography scale where a configurable `base-size` in [`shell.toml`](https://github.com/omacom/omarchy/blob/main/shell.toml) serves as the root value, and the QML `Style` singleton calculates semantic tokens using fixed multipliers for proportional scaling.**

Omarchy is an open-source desktop environment built with QML that prioritizes consistent theming across its shell components. The **typography scale management** system decouples configuration from rendering, allowing themes to establish a base font size that automatically propagates to all UI text elements while supporting per-token overrides for precise control.

## Architecture of the Typography System

The typography architecture follows a two-layer approach: **configuration** happens in TOML files, while **calculation and exposure** occurs in QML singletons.

### The Rem Root in shell.toml

Every Omarchy theme derives its typography from a single source of truth defined in [`shell.toml`](https://github.com/omacom/omarchy/blob/main/shell.toml). The template file [`default/themed/shell.toml.tpl`](https://github.com/omacom/omarchy/blob/quattro/default/themed/shell.toml.tpl#L101) establishes the `[font]` section where `base-size` functions as the rem root:

```toml
[font]
base-size = 12

```

As documented in lines 101-106 of the template, this base size anchors the entire scale. The comment explicitly states: *"base-size is the rem root for the type scale. Every Style.font.<token> derives from it (e.g. body = base, subtitle ≈ base * 1.083, heading ≈ base * 1.333)."*

### QML Calculation Engine in Style.qml

The singleton [`shell/Commons/Style.qml`](https://github.com/omacom/omarchy/blob/quattro/shell/Commons/Style.qml) ingests the configuration through `applyShellValues` (lines 20-24) and stores the base size in `fontBaseSize`. Two helper functions handle the mathematics:

```qml
function fontPx(mult) { return Math.max(1, Math.round(fontBaseSize * mult)) }
function fontToken(key, fallback) {
    var v = fontOverrides[key]; var n = Number(v);
    return (isFinite(n) && n > 0) ? Math.round(n) : fallback;
}

```

These functions appear at lines 84-95 in `Style.qml`. The `fontPx` function ensures no size drops below 1 pixel, while `fontToken` checks for user-defined overrides before falling back to calculated values.

## Semantic Token Definitions

The `Style` singleton exposes eight semantic typography tokens as read-only properties. Each token uses `fontToken` with a multiplier-based fallback generated by `fontPx`. Lines 27-35 in `Style.qml` define the scale:

```qml
readonly property int caption:      root.fontToken("caption",       root.fontPx(0.833))   // 10
readonly property int bodySmall:    root.fontToken("body-small",    root.fontPx(0.917))   // 11
readonly property int body:         root.fontToken("body",         root.fontPx(1.0))     // 12
readonly property int subtitle:     root.fontToken("subtitle",     root.fontPx(1.083))   // 13
readonly property int title:        root.fontToken("title",        root.fontPx(1.167))   // 14
readonly property int heading:      root.fontToken("heading",      root.fontPx(1.333))   // 16
readonly property int display:      root.fontToken("display",      root.fontPx(2.0))     // 24
readonly property int displayLarge: root.fontToken("display-large",root.fontPx(2.333))   // 28

```

With a default `base-size` of 12, these multipliers produce pixel values ranging from 10px (caption) to 28px (displayLarge). Changing the base size automatically recalculates every token proportionally.

## Override System for Granular Control

Themes can **pin** specific tokens without disrupting the proportional scale. By adding keys under `[font]` in [`shell.toml`](https://github.com/omacom/omarchy/blob/main/shell.toml), you override individual values while preserving the rem calculations for others.

For example, to increase only the heading size while keeping the rest of the scale tied to the 12px base:

```toml
[font]
base-size = 12
heading   = 20

```

The `fontToken` function detects the `heading` override and returns `20` directly, while `body`, `title`, and other tokens continue calculating from `base-size * multiplier`.

## Scaling UI Elements with Typography

Omarchy optionally couples spacing and bar dimensions to the **typography scale** through the `fontScale` property. Defined at line 84 in `Style.qml` as:

```qml
readonly property real fontScale: Math.max(1 / 12, fontBaseSize / 12)

```

This normalization factor enables proportional scaling of non-text elements. When [`shell.toml`](https://github.com/omacom/omarchy/blob/main/shell.toml) contains:

```toml
[spacing]
scale-with-font = true

[bar]
scale-with-font = true

```

The shell multiplies gap sizes and panel dimensions by `fontScale`, ensuring that increasing the base font size grows the entire UI density appropriately.

## Practical Configuration Examples

### Changing Base Size via CLI

Use the built-in helper to inspect or modify the rem root:

```bash

# Check current base size

omarchy display text size

# Set to 14px (increases whole scale)

omarchy display text size 14

```

This command updates `[font] base-size` in `~/.config/omarchy/shell.toml`. The change propagates instantly to all `Style.font.*` references throughout the QML shell.

### Pinning Specific Tokens

Create a custom theme that keeps the default scale but enlarges headings:

```toml
[font]
base-size = 12
heading   = 20
display   = 32

```

### Accessing Tokens in QML Components

UI elements consume the singleton directly:

```qml
Text {
    text: "Window Title"
    font.pixelSize: Style.font.title
    font.family: Style.font.family
}

```

### Disabling Proportional Scaling

To keep spacing and bar sizes fixed regardless of font changes:

```toml
[spacing]
scale-with-font = false

[bar]
scale-with-font = false

```

## Summary

- **Omarchy typography** relies on a rem-style system configured in [`shell.toml`](https://github.com/omacom/omarchy/blob/main/shell.toml) and implemented in `shell/Commons/Style.qml`.
- The `base-size` key serves as the root value; all semantic tokens calculate from it using fixed multipliers ranging from 0.833 (caption) to 2.333 (displayLarge).
- The `fontToken` function supports per-token overrides, allowing themes to pin specific sizes while maintaining proportional scaling for the rest.
- **Typography scale** changes can automatically adjust spacing and bar dimensions through the `fontScale` property when `scale-with-font` is enabled.
- Modifications take effect immediately across the QML shell via the `Style` singleton.

## Frequently Asked Questions

### What file controls the base typography size in Omarchy?

The `[font] base-size` key in [`shell.toml`](https://github.com/omacom/omarchy/blob/main/shell.toml) controls the root size. This file is typically generated from the template at [`default/themed/shell.toml.tpl`](https://github.com/omacom/omarchy/blob/quattro/default/themed/shell.toml.tpl) and located at `~/.config/omarchy/shell.toml` in active configurations. The CLI tool `omarchy display text size` provides a convenient interface to read and write this value.

### How do I change only the heading size without affecting body text?

Add a `heading` key under the `[font]` section in your theme's [`shell.toml`](https://github.com/omacom/omarchy/blob/main/shell.toml). Because the `fontToken` function checks for overrides before applying multipliers, specifying `heading = 20` pins that token to 20px while `body`, `subtitle`, and other tokens continue calculating from the `base-size` rem root.

### What is the default base font size in Omarchy themes?

The default `base-size` is `12` pixels, as defined in the template configuration. This produces a body text size of 12px, subtitle at 13px, title at 14px, and heading at 16px according to the multiplier ratios implemented in `Style.qml`.

### How does typography scaling affect panel and window spacing?

When `[spacing] scale-with-font` or `[bar] scale-with-font` is set to `true` in [`shell.toml`](https://github.com/omacom/omarchy/blob/main/shell.toml), the shell uses the `fontScale` property (calculated as `fontBaseSize / 12`) to multiply gap sizes, margins, and bar dimensions. This ensures that increasing the base font size proportionally increases UI whitespace, maintaining visual harmony across different density preferences.