Customizing ImGui Theme and Style: A Complete Guide to ImGuiStyle

Dear ImGui's appearance is controlled entirely through the ImGuiStyle structure, which you can modify at initialization via ImGui::GetStyle() or temporarily per-widget using the PushStyleVar/PushStyleColor stack API.

Dear ImGui (ocornut/imgui) exposes every visual parameter through a single plain-old-data structure, making customizing ImGui theme and style straightforward once you understand the ImGuiStyle fields and the built-in palette helpers. The style system is defined in imgui.h and implemented across imgui_draw.cpp and imgui.cpp, giving you full access to colors, spacing, rounding, and layout constants. Whether you want a dark, light, or fully bespoke look, you can achieve it by manipulating this structure before the first ImGui::NewFrame() call.

Customizing ImGui Theme and Style with the ImGuiStyle Structure

The foundation of every Dear ImGui theme is the ImGuiStyle structure declared in imgui.h around lines 2308–2399. It is a flat POD struct that holds scalar float and ImVec2 fields—such as WindowPadding, FrameRounding, and ItemSpacing—plus a Colors[ImGuiCol_COUNT] array that stores an ImVec4 for every color index defined by the ImGuiCol_ enum. Because it is plain data with no hidden state, you can copy, compare, or serialize the entire structure with standard C++.

Built-In Palette Helpers for Quick Theme Presets

Dear ImGui ships with three preset color schemes implemented in imgui_draw.cpp. These functions populate a fresh ImGuiStyle with curated palettes:

  • ImGui::StyleColorsDark() – The modern dark theme (default). Implementation occupies imgui_draw.cpp lines 887–954.

  • ImGui::StyleColorsClassic() – The original ImGui look from early versions. Implementation occupies lines 955–1022.

  • ImGui::StyleColorsLight() – A light-colored scheme for bright environments. Implementation occupies lines 1023–1085.

Each helper accepts an optional ImGuiStyle* pointer; passing one writes the palette into your existing instance instead of the global style.

Applying a Custom Theme Before the First Frame

The recommended workflow for customizing ImGui theme and style is to perform changes once during application initialization, before the first call to ImGui::NewFrame(). You can either overwrite the global style returned by ImGui::GetStyle() or fill a local ImGuiStyle and assign it.

// 1️⃣ Initialise a custom dark theme with a few tweaks
ImGuiStyle customStyle;
ImGui::StyleColorsDark(&customStyle);           // start from built‑in dark palette

// Override a few colours
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);

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

// Apply it before the first frame
ImGui::GetStyle() = customStyle;   // or: ImGui::GetStyle() = customStyle; (C++ copy)

Calling ImGui::GetStyle() = customStyle; performs a plain struct copy, so all colors and metrics take effect globally for the remainder of the session.

Runtime Style Overrides Using the Push/Pop Stack

When you need temporary, scoped changes—such as turning a single button red—you should avoid mutating the global style directly. Instead, use the stack-based API declared in imgui.h lines 527–560:

  • ImGui::PushStyleVar(ImGuiStyleVar_idx, value) / ImGui::PopStyleVar() – For numeric and ImVec2 metrics.

  • ImGui::PushStyleColor(ImGuiCol_idx, color) / ImGui::PopStyleColor() – For color overrides.

Behind the scenes, these calls store ImGuiStyleMod objects defined in imgui_internal.h, so the previous value is restored automatically when you pop.

// 2️⃣ Temporary per‑frame tweaks using the stack API
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 12.0f);
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.9f, 0.2f, 0.2f, 1.0f));

// ... draw UI ...

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

Prototyping Themes with ShowStyleEditor()

Dear ImGui includes a built-in visual editor for rapid theme tweaking. The ImGui::ShowStyleEditor() function, declared in imgui.h at line 414, opens a debug window that edits the current global style in real time.

// 3️⃣ Show the live editor (useful for rapid prototyping)
ImGui::ShowStyleEditor();   // opens a window that edits ImGui::GetStyle()

Use this to find the exact color indices and metric values you want, then transfer those values into your initialization code or serialization format.

Serializing Custom ImGui Themes for Persistence

Because ImGuiStyle is simple POD data, you can persist it to JSON, INI, or binary and reload it at runtime. This enables user-adjustable themes across sessions. The example below uses nlohmann/json to store the Alpha, rounding, and Colors array:

// 4️⃣ Serialize/deserialize a style (example with JSON – requires nlohmann/json)
#include <nlohmann/json.hpp>

void SaveStyle(const ImGuiStyle& style, const std::string& path)
{
    nlohmann::json j;
    j["Alpha"] = style.Alpha;
    j["WindowRounding"] = style.WindowRounding;
    // ... (store every scalar you care about)
    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 all 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 Dear ImGui releases may add new fields to ImGuiStyle. Persisted themes should be version-checked or rebuilt against the latest defaults to avoid layout mismatches.

Key Files in the Dear ImGui Source

File Purpose
imgui.h Public API declarations for ImGuiStyle, push/pop functions, and ShowStyleEditor (lines 527–560 and 2308–2399).
imgui_draw.cpp Implementations of StyleColorsDark, StyleColorsClassic, and StyleColorsLight (lines 887–1085).
imgui_internal.h Internal ImGuiStyleMod struct that backs the push/pop stack.
imgui.cpp Usage comments and evolution notes on the style system.

Summary

  • ImGuiStyle is the single POD structure that defines every color, padding, and rounding value in Dear ImGui.

  • Call ImGui::StyleColorsDark(), StyleColorsClassic(), or StyleColorsLight() to populate a baseline palette from imgui_draw.cpp.

  • Assign your customized struct to ImGui::GetStyle() once at startup, before the first NewFrame().

  • Use PushStyleVar / PushStyleColor and the corresponding Pop* calls for temporary, scoped overrides.

  • Leverage ImGui::ShowStyleEditor() to prototype themes interactively.

  • Serialize the struct to JSON or binary if you want persistent, user-customizable themes, but guard against future struct layout changes.

Frequently Asked Questions

How do I change the default theme in Dear ImGui?

Call one of the built-in palette helpers—such as ImGui::StyleColorsDark(), ImGui::StyleColorsClassic(), or ImGui::StyleColorsLight()—before your first ImGui::NewFrame(). You can pass a pointer to your own ImGuiStyle instance or let the function update the global style directly.

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

Modifying ImGui::GetStyle() changes the global theme permanently until you overwrite it again, so it is best done once at initialization. In contrast, PushStyleColor and PushStyleVar apply temporary overrides on a stack that are automatically reverted when you call the corresponding Pop*() function, making them ideal for one-off widget variations.

Can I save and load custom ImGui themes at runtime?

Yes. Because ImGuiStyle is plain-old-data, you can serialize its scalar fields and Colors array to JSON, INI, or binary and deserialize them back into the struct. Just ensure you validate the data version when upgrading Dear ImGui, since newer releases may extend the struct with additional fields.

Where are the default ImGui theme colors defined?

The default dark, classic, and light palettes are implemented in imgui_draw.cpp between lines 887 and 1085. Each palette function explicitly sets every entry of the Colors array using hard-coded ImVec4 values.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →