How to Customize Dear ImGui Styling and Themes Programmatically
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/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/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.
// 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/master/imgui.cpp#L4235), create internal ImGuiStyleMod structures (defined in [imgui_internal.h](https://github.com/ocornut/imgui/blob/master/imgui_internal.h#L954)) that store the original values on a stack.
// 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/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/master/imgui.cpp#L4525), renders a collapsible panel with live controls for every ImGuiStyle field and color entry.
// 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:
// 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:
// 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
ImGuiStylestructure accessible viaImGui::GetStyle()in [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/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/master/imgui_internal.h#L954). - Enumerations
ImGuiStyleVar_andImGuiCol_provide type-safe indices for all styleable properties. ShowStyleEditorprovides 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/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.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →