# How to Customize ImGui Styling and Themes: A Complete Guide to ImGuiStyle

> Customize ImGui styling and themes effortlessly. Learn to modify ImGuiStyle, apply presets like StyleColorsDark, and use stack APIs for temporary overrides. Enhance your UI today.

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

---

**Customize ImGui styling and themes by modifying the `ImGuiStyle` structure via `ImGui::GetStyle()`, applying built-in presets like `StyleColorsDark()`, or using the `PushStyleVar()` and `PushStyleColor()` stack APIs for temporary overrides.**

Dear ImGui's appearance is controlled entirely through a single public data structure. If you want to customize ImGui styling and themes in the `ocornut/imgui` repository, you will work directly with the `ImGuiStyle` struct defined in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h). The library provides both global initialization helpers and per-frame stack APIs so you can tweak everything from button rounding to window background colors.

## Understanding the ImGuiStyle Structure

The foundation of every custom theme is the **`ImGuiStyle`** structure defined in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) around lines 2308-2399. It stores the full look-and-feel state as plain old data, including scalar fields for spacing, rounding, and borders, plus a `Colors[ImGuiCol_COUNT]` array that maps `ImGuiCol_` enum values to RGBA vectors.

Because it is a POD struct with no hidden state, you can copy, compare, or serialize it freely. The active style instance is retrieved with `ImGui::GetStyle()` and should generally be modified once during setup, before your first call to `ImGui::NewFrame()`.

## Built-In Theme Presets: Dark, Classic, and Light

Dear ImGui ships with three official preset palettes implemented in [`imgui_draw.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_draw.cpp) between lines 887 and 1085. These helper functions populate an `ImGuiStyle` with a complete color scheme:

- **`ImGui::StyleColorsDark()`** — Lines 887-954. The modern dark theme used by default.
- **`ImGui::StyleColorsClassic()`** — Lines 955-1022. The legacy orange-tinted theme.
- **`ImGui::StyleColorsLight()`** — Lines 1023-1085. A light alternative for bright environments.

Each function takes an optional `ImGuiStyle*` pointer; passing your own struct lets you start from a known baseline without mutating the global style immediately.

## Applying a Global Custom Theme at Initialization

The standard workflow is to create a local `ImGuiStyle`, run a preset through it, override specific colors or metrics, then copy it into the global state:

```cpp
// Start from the built-in dark palette
ImGuiStyle customStyle;
ImGui::StyleColorsDark(&customStyle);

// Override specific colors using the ImGuiCol_ enum
customStyle.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.2f, 0.4f, 0.9f, 1.0f);
customStyle.Colors[ImGuiCol_Button]        = ImVec4(0.1f, 0.7f, 0.3f, 0.8f);

// Adjust geometry and rounding
customStyle.WindowRounding = 6.0f;
customStyle.FrameRounding  = 4.0f;
customStyle.WindowPadding  = ImVec2(12, 12);
customStyle.ItemSpacing    = ImVec2(8, 8);

// Apply before the first frame
ImGui::GetStyle() = customStyle;

```

Setting `ImGui::GetStyle()` via assignment copies the entire structure into the current context. This approach is the recommended way to customize ImGui styling and themes for an entire application session.

## Temporary Runtime Overrides with Push and Pop

Not every style change should last for the whole session. Dear ImGui provides a stack-based API declared in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) around lines 527-560 that lets you push temporary values for a single window or widget group. Behind the scenes, the library records these changes as `ImGuiStyleMod` objects, as seen in [`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/imgui_internal.h).

- **`ImGui::PushStyleVar()`** / **`ImGui::PopStyleVar()`** — Modify numeric fields like rounding or padding.
- **`ImGui::PushStyleColor()`** / **`ImGui::PopStyleColor()`** — Modify color entries.

A typical usage block looks like this:

```cpp
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 12.0f);
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.9f, 0.2f, 0.2f, 1.0f));

// Draw affected widgets here
if (ImGui::Button("Danger")) { /* ... */ }

ImGui::PopStyleColor();
ImGui::PopStyleVar();

```

Always match the number of push and pop calls within the same frame to avoid stack corruption.

## Interactive Prototyping with ShowStyleEditor

If you prefer to tune values visually, `ImGui::ShowStyleEditor()` declared in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) at line 414 opens an integrated window that edits `ImGui::GetStyle()` in real time. This is the fastest way to experiment with metrics before hard-coding them into your initialization routine.

```cpp
// Call anywhere inside your main loop
ImGui::ShowStyleEditor();

```

Once you find a combination you like, read the values back from `ImGui::GetStyle()` and save them to your own configuration format.

## Serializing and Reloading Custom Themes

Because `ImGuiStyle` is plain data, you can persist customized themes to JSON, INI, or binary files and reload them at runtime. This enables user-adjustable themes without recompiling. Below is a JSON-oriented example using nlohmann/json:

```cpp
#include <nlohmann/json.hpp>
#include <fstream>

void SaveStyle(const ImGuiStyle& style, const std::string& path)
{
    nlohmann::json j;
    j["Alpha"] = style.Alpha;
    j["WindowRounding"] = style.WindowRounding;
    // ... store additional scalars as needed ...
    
    for (int i = 0; i < ImGuiCol_COUNT; ++i)
        j["Colors"][i] = {style.Colors[i].x, style.Colors[i].y,
                          style.Colors[i].z, style.Colors[i].w};
    
    std::ofstream f(path);
    f << j.dump(4);
}

void LoadStyle(ImGuiStyle& style, const std::string& path)
{
    std::ifstream f(path);
    nlohmann::json j;
    f >> j;
    
    style.Alpha = j["Alpha"];
    style.WindowRounding = j["WindowRounding"];
    // ... load additional scalars ...
    
    for (int i = 0; i < ImGuiCol_COUNT; ++i)
    {
        auto c = j["Colors"][i];
        style.Colors[i] = ImVec4(c[0], c[1], c[2], c[3]);
    }
}

```

Be aware that future releases of Dear ImGui may add new fields to `ImGuiStyle`. Version-check your saved data or merge missing fields against current defaults when loading older theme files.

## Key Source Files for Theme Customization

When reading the `ocornut/imgui` source to deepen your understanding, focus on these files:

- **[`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h)** — Public API declarations including `ImGuiStyle`, the `ImGuiCol_` enum, push/pop functions, and `ShowStyleEditor()`.
- **[`imgui_draw.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_draw.cpp)** — Implementations of `StyleColorsDark()`, `StyleColorsClassic()`, and `StyleColorsLight()`.
- **[`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/imgui_internal.h)** — Internal structures such as `ImGuiStyleMod` that power the push/pop stack.
- **[`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp)** — Commentary on style system evolution around lines 1000-1600.

## Summary

- **`ImGuiStyle`** is the central POD struct that controls every visual aspect of Dear ImGui.
- Use **`StyleColorsDark()`**, **`StyleColorsClassic()`**, or **`StyleColorsLight()`** in [`imgui_draw.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_draw.cpp) to establish a baseline palette.
- Apply global changes by writing to `ImGui::GetStyle()` before the first `ImGui::NewFrame()`.
- Use **`PushStyleVar()`** and **`PushStyleColor()`** for temporary, scoped overrides that automatically restore previous values.
- Call **`ShowStyleEditor()`** for interactive prototyping, then serialize your final `ImGuiStyle` to disk for reusable themes.

## Frequently Asked Questions

### How do I change the default theme in Dear ImGui?

Call one of the preset functions on a local `ImGuiStyle` object and copy it into `ImGui::GetStyle()` before your main loop starts. For example, invoke `ImGui::StyleColorsLight(&myStyle);` followed by `ImGui::GetStyle() = myStyle;` to switch the entire application to the light theme.

### What is the difference between PushStyleColor and editing ImGui::GetStyle() directly?

`PushStyleColor()` and `PushStyleVar()` create temporary, stack-based overrides that last until their matching `Pop` call, making them ideal for short-lived changes on specific widgets. Editing `ImGui::GetStyle()` directly changes the global defaults for the rest of the session or until you overwrite it again.

### Can I save and load custom ImGui themes at runtime?

Yes. Because `ImGuiStyle` is a simple C++ struct with no private state, you can serialize its scalar fields and `Colors` array to JSON or binary and reload them later. Just ensure you handle version mismatches when upgrading to newer Dear ImGui releases that may add new style fields.

### Where are the built-in color themes defined in the ImGui source code?

The built-in themes are implemented in **[`imgui_draw.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_draw.cpp)** between lines 887 and 1085. `StyleColorsDark()` occupies lines 887-954, `StyleColorsClassic()` lines 955-1022, and `StyleColorsLight()` lines 1023-1085.