# How to Customize CodexBar: Complete Settings and Configuration Guide

> Customize CodexBar fully using SettingsStore App Group UserDefaults and SwiftUI. Our guide explains all settings and configurations for this menu-bar app.

- Repository: [Peter Steinberger/CodexBar](https://github.com/steipete/CodexBar)
- Tags: how-to-guide
- Published: 2026-07-07

---

**Yes, CodexBar can be fully customized through its central `SettingsStore`, which persists user preferences in App Group UserDefaults and drives every aspect of the menu-bar behavior via SwiftUI bindings.**

CodexBar, developed by steipete, is a macOS menu-bar application for monitoring AI API usage from providers like OpenAI Codex and Anthropic Claude. Unlike static utilities, CodexBar is engineered around a reactive configuration architecture that exposes every behavioral aspect—from data refresh intervals to visual metric displays—through a type-safe observable API.

## The SettingsStore Architecture

### Observable Singleton Pattern

At the heart of CodexBar customization lies **`SettingsStore`**, an `@Observable` singleton defined in [`Sources/CodexBar/SettingsStore.swift`](https://github.com/steipete/CodexBar/blob/main/Sources/CodexBar/SettingsStore.swift). This class serves as the single source of truth for all user preferences, exposing strongly-typed properties that SwiftUI views bind to directly. When any setting value mutates, the observable macro pushes updates immediately to the UI layer, ensuring the menu-bar icon and dropdown reflect new configurations in real time without manual refresh.

### Persistence via App Group UserDefaults

The store synchronizes state with `UserDefaults` using a shared App Group container. The **`loadDefaultsState`** method (lines 73-80) handles deserialization, mapping string keys like `"refreshFrequency"` to enum-backed properties such as `RefreshFrequency`. All writes propagate back to the same defaults suite via symmetric serialization logic, ensuring preferences survive app restarts and remain accessible to the main process and any system extensions.

## Customizable Behavior Categories

### Refresh Strategy and Timing

Users control data polling aggressiveness through the **`refreshFrequency`** property. Options include manual refresh, fixed intervals (e.g., `oneMinute`), or adaptive backoff strategies. This enum is defined in `SettingsStore` and surfaced in the UI through components in [`PreferencesMenuPicker.swift`](https://github.com/steipete/CodexBar/blob/main/PreferencesMenuPicker.swift).

### Menu Bar Appearance

The **`menuBarMetricPreference`** property determines which usage statistic appears in the menu bar—primary tokens, secondary metrics, rolling averages, or monthly plan totals. Additionally, the boolean **`mergeIcons`** toggles whether CodexBar renders a single consolidated icon for all providers or maintains separate status icons per service.

### Provider-Specific Configuration

Each AI provider is represented by the **`UsageProvider`** enum. The sidebar automatically instantiates a configuration pane for each detected provider using **`providerEnablement`** and **`selectedMenuProviderRawStorage`**. These keys control API authentication, cookie handling policies, and service-specific feature toggles, all managed within the same observable store.

### System Integration and Debugging

Advanced customization includes **`launchAtLogin`** for startup behavior and **`debugMenuEnabled`** for exposing internal diagnostics. These boolean flags are stored alongside core preferences and can be toggled either through the Settings window or programmatically via the store’s public API.

## Programmatic Customization

Developers and power users can automate CodexBar configuration by interacting with `SettingsStore.shared`:

```swift
import CodexBar

// Access the shared settings store (singleton)
let settings = SettingsStore.shared

// Change the refresh frequency to “one minute”
settings.refreshFrequency = .oneMinute

// Show the primary metric only (no secondary)
settings.menuBarMetricPreference = .primary

// Enable icon merging (single merged icon for all providers)
settings.mergeIcons = true

// Turn on the hidden debug menu (useful for development)
settings.debugMenuEnabled = true

// Enable launch‑at‑login
settings.launchAtLogin = true

// Programmatically select a provider‑specific pane in the preferences window
// (e.g., open the Claude pane)
preferencesSelection.pane = .provider(.claude)

```

All properties above map directly to fields in `SettingsStore` (lines 75-87). To add custom UI settings, extend the class with new `@Published` properties and update the `loadDefaultsState`/`storeDefaultsState` logic to handle persistence.

## Key Files Governing Customization

Every customization surface is implemented across these specific source files:

- **[`Sources/CodexBar/SettingsStore.swift`](https://github.com/steipete/CodexBar/blob/main/Sources/CodexBar/SettingsStore.swift)** – Core observable model that stores every user preference and manages UserDefaults serialization.
- **[`Sources/CodexBar/PreferencesView.swift`](https://github.com/steipete/CodexBar/blob/main/Sources/CodexBar/PreferencesView.swift)** – SwiftUI wrapper (lines 34-45) that binds UI controls to `SettingsStore` and manages the settings window layout.
- **[`Sources/CodexBar/PreferencesSidebar.swift`](https://github.com/steipete/CodexBar/blob/main/Sources/CodexBar/PreferencesSidebar.swift)** – Constructs the settings sidebar, including dynamic entries for each `UsageProvider` case.
- **[`Sources/CodexBar/PreferencesMenuPicker.swift`](https://github.com/steipete/CodexBar/blob/main/Sources/CodexBar/PreferencesMenuPicker.swift)** – Reusable picker components used for enum-based settings like refresh intervals.
- **[`Sources/CodexBar/PreferencesComponents.swift`](https://github.com/steipete/CodexBar/blob/main/Sources/CodexBar/PreferencesComponents.swift)** – UI primitives (rows, sections, icons) that render the settings interface.
- **`SettingsPane` enum** (inside [`PreferencesView.swift`](https://github.com/steipete/CodexBar/blob/main/PreferencesView.swift)) – Defines the complete set of panes displayed in the settings window, including static sections and provider-specific dynamic entries.

## Summary

- CodexBar customization centers on the `@Observable` **`SettingsStore`** singleton in [`Sources/CodexBar/SettingsStore.swift`](https://github.com/steipete/CodexBar/blob/main/Sources/CodexBar/SettingsStore.swift).
- Preferences persist in **App Group UserDefaults** and load automatically via `loadDefaultsState`.
- Configurable aspects include refresh frequency, menu bar metrics, icon merging, provider-specific enablement, and system startup behavior.
- Changes propagate instantly through SwiftUI bindings without requiring app restarts.
- Programmatic access is available via `SettingsStore.shared` for automation, plugins, or advanced scripting workflows.

## Frequently Asked Questions

### Where does CodexBar store its settings on macOS?

CodexBar persists configuration in **App Group UserDefaults**, accessible to both the main application and its system extensions. The `SettingsStore` class handles all serialization in [`Sources/CodexBar/SettingsStore.swift`](https://github.com/steipete/CodexBar/blob/main/Sources/CodexBar/SettingsStore.swift), mapping properties to standardized keys like `"refreshFrequency"` and `"mergeIcons"` (lines 75-87).

### Do I need to restart CodexBar after changing preferences?

No. Because `SettingsStore` uses the **`@Observable`** macro (SwiftUI’s modern observation framework), any property change immediately triggers view updates. The menu-bar controller reads the observable state on every mutation, applying new refresh policies, metric displays, or icon configurations dynamically without requiring a relaunch.

### Can I customize which AI providers CodexBar monitors?

Yes. The **`UsageProvider`** enum supports multiple providers including Codex and Claude. The sidebar in [`PreferencesSidebar.swift`](https://github.com/steipete/CodexBar/blob/main/PreferencesSidebar.swift) automatically generates configuration panes for each detected provider, allowing separate management of API tokens and service enablement via `providerEnablement` and `selectedMenuProviderRawStorage` dictionaries.

### How do I enable the debug menu in CodexBar?

Set **`settings.debugMenuEnabled = true`** on the shared `SettingsStore` instance, or toggle the option in the Advanced settings pane. This exposes internal diagnostics and development tools useful for troubleshooting API connectivity, inspecting raw network responses, or verifying data refresh cycles.