# How to Customize Dear ImGui Styling and Themes Programmatically

> Learn to customize Dear ImGui styling and themes. Modify colors, sizes, and rounding programmatically with ImGuiStyle for a unique look.

- Repository: [omar/imgui](https://github.com/ocornut/imgui)
- Tags: how-to-guide
- Published: 2026-07-14

---

**Dear ImGui's appearance is controlled by the `ImGuiStyle` structure accessible via `ImGui::GetStyle()`, allowing you to modify colors, sizes, and rounding values directly or through temporary stack-based overrides.**

When building immediate-mode user interfaces with the **ocornut/imgui** library, customizing the visual appearance is essential for professional applications. The styling system centers around a single structure that holds all aesthetic parameters, from window padding to color palettes. Understanding how to programmatically manipulate this structure enables you to create anything from subtle tweaks to complete visual overhauls.

## Understanding the ImGuiStyle Architecture

The styling system in Dear ImGui relies on a centralized structure that persists across frames while providing mechanisms for both global and temporary modifications.

### The Style Storage System

At the core of Dear ImGui's theming lies the **`ImGuiStyle`** structure, which resides inside the global **`ImGuiIO`** object. You can obtain a reference to the active style instance by calling `ImGui::GetStyle()`. This structure, defined in [[`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h)](https://github.com/ocornut/imgui/blob/master/imgui.h#L176), contains all the **float** values for spacing, rounding, and alignment, plus a **`Colors`** array indexed by the **`ImGuiCol_`** enumeration. The style instance is created once during context initialization and reused every frame, making global modifications persist until explicitly changed.

### Default Theme Functions

Dear ImGui provides three built-in preset themes that populate the style structure with curated color palettes. The functions **`StyleColorsDark()`**, **`StyleColorsLight()`**, and **`StyleColorsClassic()`** are implemented in [[`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp)](https://github.com/ocornut/imgui/blob/master/imgui.cpp#L4375) as simple `void` functions that accept an optional destination pointer. These helpers write predefined **`ImVec4`** values into the `Colors` array and set sensible defaults for size-related fields. Calling one of these functions at application startup establishes your base aesthetic before applying custom overrides.

## Modifying Styles at Runtime

Dear ImGui offers two distinct approaches for altering appearance: direct structure manipulation for permanent changes, and stack-based modifications for temporary widget-specific styling.

### Global Style Modifications

For changes that should persist across your entire application, modify the **`ImGuiStyle`** structure directly through the reference returned by `ImGui::GetStyle()`. This approach updates the global state immediately and affects all subsequent draw calls until the next modification.

```cpp
// Obtain reference to the global style
ImGuiStyle& style = ImGui::GetStyle();

// Modify structural properties
style.WindowRounding = 8.0f;
style.FramePadding = ImVec2(8.0f, 4.0f);
style.GrabMinSize = 12.0f;

// Update color values using the ImGuiCol_ enum
style.Colors[ImGuiCol_Text] = ImVec4(1.0f, 0.95f, 0.6f, 1.0f);
style.Colors[ImGuiCol_WindowBg] = ImVec4(0.1f, 0.1f, 0.1f, 0.95f);

```

### Temporary Stack-Based Overrides

When you need to modify appearance for only a specific widget or group of widgets, use the **push/pop API** to avoid polluting the global state. The `PushStyleVar` and `PushStyleColor` functions, implemented in [[`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp)](https://github.com/ocornut/imgui/blob/master/imgui.cpp#L4235), create internal **`ImGuiStyleMod`** structures (defined in [[`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/imgui_internal.h)](https://github.com/ocornut/imgui/blob/master/imgui_internal.h#L954)) that store the original values on a stack.

```cpp
// Temporarily increase frame rounding for the next widget
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 12.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10.0f, 6.0f));
ImGui::Button("Rounded Button");
ImGui::PopStyleVar(2);  // Restore both variables

// Temporarily change button color
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.7f, 0.2f, 1.0f));
ImGui::Button("Green Button");
ImGui::PopStyleColor();

```

The **`ImGuiStyleVar_`** enumeration (defined in [[`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h)](https://github.com/ocornut/imgui/blob/master/imgui.h#L1812)) lists every mutable float and **`ImVec2`** field, while **`ImGuiCol_`** enumerates the color slots available for override.

## Interactive Style Discovery

Rather than guessing values, you can inspect and modify the entire style structure at runtime using the built-in style editor. The function **`ImGui::ShowStyleEditor()`**, implemented in [[`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp)](https://github.com/ocornut/imgui/blob/master/imgui.cpp#L4525), renders a collapsible panel with live controls for every **`ImGuiStyle`** field and color entry.

```cpp
// Inside your main loop after ImGui::NewFrame()
ImGui::ShowStyleEditor();  // Interactive editor appears in UI

```

This tool reflects the current state of `ImGui::GetStyle()` and updates values in real-time, making it invaluable for discovering the exact field names and tuning values before hardcoding them.

## Practical Implementation Examples

### Applying a Built-in Theme with Overrides

Start with a preset theme, then apply specific customizations:

```cpp
// Initialize with dark theme
ImGui::StyleColorsDark();

// Reference to modify
ImGuiStyle& style = ImGui::GetStyle();

// Customize specific elements
style.WindowRounding = 6.0f;
style.FrameRounding = 3.0f;
style.GrabRounding = 4.0f;
style.Colors[ImGuiCol_Text] = ImVec4(0.9f, 0.9f, 0.9f, 1.0f);
style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.3f, 0.5f, 0.8f, 1.0f);

```

### Persisting Custom Themes

To save and load custom themes between sessions, serialize the **`ImGuiStyle`** structure to a file format such as JSON:

```cpp
// Saving style to JSON
ImGuiStyle& style = ImGui::GetStyle();
nlohmann::json j;

// Serialize all colors
for (int i = 0; i < ImGuiCol_COUNT; ++i) {
    j["Colors"][ImGui::GetStyleColorName(i)] = {
        style.Colors[i].x, style.Colors[i].y,
        style.Colors[i].z, style.Colors[i].w
    };
}

// Serialize scalar values
j["Alpha"] = style.Alpha;
j["WindowRounding"] = style.WindowRounding;
j["FrameRounding"] = style.FrameRounding;
j["GrabMinSize"] = style.GrabMinSize;

// Write to file
std::ofstream("custom_theme.json") << j.dump(4);

```

Loading reverses this process, deserializing values back into the **`ImGuiStyle`** structure before the first frame renders.

## Summary

- **Dear ImGui styling** centers on the **`ImGuiStyle`** structure accessible via `ImGui::GetStyle()` in [[`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h)](https://github.com/ocornut/imgui/blob/master/imgui.h).
- **Built-in themes** (`StyleColorsDark`, `StyleColorsLight`, `StyleColorsClassic`) establish base palettes defined in [[`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp)](https://github.com/ocornut/imgui/blob/master/imgui.cpp#L4375).
- **Direct modification** of `ImGui::GetStyle()` creates persistent global changes to colors and metrics.
- **Push/Pop API** (`PushStyleVar`, `PushStyleColor`) enables temporary overrides without affecting global state, using the stack mechanism defined in [[`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/imgui_internal.h)](https://github.com/ocornut/imgui/blob/master/imgui_internal.h#L954).
- **Enumerations** `ImGuiStyleVar_` and `ImGuiCol_` provide type-safe indices for all styleable properties.
- **`ShowStyleEditor`** provides an interactive interface for discovering and tuning style values in real-time.

## Frequently Asked Questions

### How do I access the current ImGui style structure?

Call **`ImGui::GetStyle()`**, which returns a reference to the **`ImGuiStyle`** instance stored in the global **`ImGuiIO`** object. This reference allows both reading current values and writing new values that persist until the next modification. The style structure contains the `Colors` array and all sizing parameters like `WindowRounding` and `FramePadding`.

### What is the difference between PushStyleVar and direct style modification?

**`PushStyleVar`** (and `PushStyleColor`) create temporary overrides that last until the matching `PopStyleVar` call, while direct modification via `ImGui::GetStyle()` changes the global state permanently. Use push/pop when styling individual widgets or small widget groups, and use direct modification for application-wide themes. The push/pop system uses an internal stack of **`ImGuiStyleMod`** structures to restore previous values.

### How can I save and load custom themes?

Serialize the **`ImGuiStyle`** structure to a file format such as JSON or INI. Iterate through the `Colors` array (size `ImGuiCol_COUNT`) and all scalar fields like `Alpha`, `WindowRounding`, and `FrameRounding`. Store these values to disk, then deserialize them back into `ImGui::GetStyle()` at application startup. This approach allows you to persist user-generated themes across sessions.

### Where can I find the list of available style variables and colors?

The **`ImGuiStyleVar_`** enumeration in [[`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h)](https://github.com/ocornut/imgui/blob/master/imgui.h#L1812) lists every mutable style variable (float and `ImVec2` types), while **`ImGuiCol_`** enumerates all color slots. Additionally, calling **`ImGui::ShowStyleEditor()`** displays an interactive panel showing every available field with live editing capabilities, making it the fastest way to discover specific fields and their current values.