# How to Integrate ImGui with Modern C++ Frameworks: A Complete Implementation Guide

> Learn to easily integrate ImGui with modern C++ frameworks. This guide details platform and renderer backend integration for a seamless development experience.

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

---

**Dear ImGui integrates into modern C++ frameworks by combining a platform backend (e.g., GLFW, SDL) with a renderer backend (e.g., OpenGL, Vulkan) and linking them to the core library sources.**

The Dear ImGui (ocornut/imgui) library provides an immediate-mode graphical user interface for C++ applications. To integrate ImGui with modern C++ frameworks, you combine the core UI library with platform-specific and renderer-specific backends, enabling everything from simple debugging tools to complex docking multi-viewport editors. This architecture keeps the library portable while allowing deep integration with your existing windowing and graphics systems.

## Understanding the Two-Layer Architecture

Dear ImGui is deliberately separated into two distinct layers. The **core UI library** (located in the repository root, including [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) and [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h)) handles widget logic, layout, and draw list generation. The **backend layer** (located in the `backends/` folder) implements platform-specific input handling and graphics-API-specific rendering. This separation allows you to mix and match backends to suit your framework's requirements.

## Selecting Your Platform Backend

The platform backend provides window creation, input polling, mouse-cursor shaping, and multi-viewport support. Choose based on your target platforms and existing dependencies.

### GLFW for Cross-Platform Windowing

**GLFW** is the most common choice for modern C++ applications on Windows, macOS, and Linux. The implementation resides in [`backends/imgui_impl_glfw.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_glfw.cpp) and [`backends/imgui_impl_glfw.h`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_glfw.h). Initialize it with your existing window pointer:

```cpp
ImGui_ImplGlfw_InitForOpenGL(window, true);

```

### SDL2 and SDL3 for Game-Engine Integration

**SDL2** offers robust controller support and is ideal for game engines. Use [`backends/imgui_impl_sdl2.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_sdl2.cpp) for SDL2 projects. For newer codebases using **SDL3**, the backend is implemented in [`backends/imgui_impl_sdl3.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_sdl3.cpp).

## Selecting Your Renderer Backend

The renderer backend translates ImGui draw commands into GPU API calls. Modern C++ frameworks typically choose based on their existing graphics abstraction.

### OpenGL 3/4 (Core Profile)

The **OpenGL 3/4** backend in [`backends/imgui_impl_opengl3.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_opengl3.cpp) works with legacy and cross-platform OpenGL projects. Initialize with your shader version string:

```cpp
ImGui_ImplOpenGL3_Init("#version 330");

```

### Vulkan for High-Performance Rendering

For explicit API control, use the **Vulkan** backend in [`backends/imgui_impl_vulkan.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_vulkan.cpp). This requires setting up a `ImGui_ImplVulkan_InitInfo` structure with your existing Vulkan instance, device, and queue:

```cpp
ImGui_ImplVulkan_InitInfo init_info = {};
init_info.Instance = vkInstance;
init_info.PhysicalDevice = vkPhysicalDevice;
init_info.Device = vkDevice;
init_info.QueueFamily = graphicsQueueFamily;
init_info.Queue = graphicsQueue;
init_info.PipelineCache = vkPipelineCache;
init_info.DescriptorPool = vkDescriptorPool;
init_info.MinImageCount = 2;
init_info.ImageCount = swapchainImageCount;
ImGui_ImplVulkan_Init(&init_info, renderPass);

```

### DirectX 11/12 for Windows-Only Applications

Windows-centric frameworks can use the **DirectX 11** or **DirectX 12** backends ([`backends/imgui_impl_dx11.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_dx11.cpp) and related files) for native integration with the Windows compositor.

## Initializing the ImGui Context

Before using any backends, create an ImGui context and configure modern features like docking and multi-viewport support. In [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), `ImGui::CreateContext()` allocates the global state:

```cpp
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;

```

## Wiring the Frame Loop

The integration requires a specific frame sequence in your main loop. According to the source code in [`imgui_impl_glfw.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_glfw.cpp) and [`imgui_impl_opengl3.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_opengl3.cpp), the order is critical:

```cpp
// Poll window events
glfwPollEvents();

// Start new frames for backends and core
ImGui_ImplGlfw_NewFrame();
ImGui_ImplOpenGL3_NewFrame();
ImGui::NewFrame();

// Build your UI
ImGui::ShowDemoWindow();

// Finalize draw data
ImGui::Render();

// Clear and setup viewport
int display_w, display_h;
glfwGetFramebufferSize(window, &display_w, &display_h);
glViewport(0, 0, display_w, display_h);
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

// Render draw data
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

// Handle multi-viewport rendering
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
    ImGui::UpdatePlatformWindows();
    ImGui::RenderPlatformWindowsDefault();
}

glfwSwapBuffers(window);

```

## CMake Integration for Modern C++

Modern C++ projects typically use CMake. A minimal [`CMakeLists.txt`](https://github.com/ocornut/imgui/blob/main/CMakeLists.txt) that compiles the required sources from the ocornut/imgui repository looks like this:

```cmake
cmake_minimum_required(VERSION 3.15)
project(MyApp LANGUAGES CXX)

set(IMGUI_DIR "${CMAKE_CURRENT_SOURCE_DIR}/imgui")
file(GLOB IMGUI_SOURCES
    "${IMGUI_DIR}/*.cpp"
    "${IMGUI_DIR}/backends/imgui_impl_glfw.cpp"
    "${IMGUI_DIR}/backends/imgui_impl_opengl3.cpp"
)
add_executable(MyApp main.cpp ${IMGUI_SOURCES})
target_include_directories(MyApp PRIVATE "${IMGUI_DIR}" "${IMGUI_DIR}/backends")
find_package(glfw3 REQUIRED)
find_package(OpenGL REQUIRED)
target_link_libraries(MyApp PRIVATE glfw OpenGL::GL)
target_compile_features(MyApp PRIVATE cxx_std_17)

```

## Advanced Features

### Multi-Viewport Support

Enable multi-viewport support by setting `ImGuiConfigFlags_ViewportsEnable` in the `ImGuiIO` structure. The platform backend automatically creates additional OS windows. Ensure your renderer backend supports `ImGuiBackendFlags_RendererHasVtxOffset` and `ImGuiBackendFlags_RendererHasTextures` flags (added in v1.92) as documented in [`docs/BACKENDS.md`](https://github.com/ocornut/imgui/blob/main/docs/BACKENDS.md).

### Custom Engine Integration

If your framework already has a rendering abstraction, you can use the standard backends as reference implementations. Replace the `RenderDrawData` implementation with calls into your own engine. The documentation in [`docs/BACKENDS.md`](https://github.com/ocornut/imgui/blob/main/docs/BACKENDS.md) provides a complete template for `MyImGuiBackend_RenderDrawData`.

## Summary

- Dear ImGui uses a two-layer architecture separating the core library from platform and renderer backends.
- Choose a **platform backend** (GLFW, SDL2, SDL3) for windowing and input, and a **renderer backend** (OpenGL 3, Vulkan, DirectX) for drawing.
- Initialize the context with `ImGui::CreateContext()` and configure modern features via `ImGuiIO` flags.
- Implement the frame loop sequence: platform `NewFrame()`, renderer `NewFrame()`, `ImGui::NewFrame()`, UI construction, `ImGui::Render()`, then platform/renderer `RenderDrawData`.
- Use CMake to compile the core files ([`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp)) alongside your selected backend implementations from the `backends/` folder.

## Frequently Asked Questions

### What is the minimum code needed to integrate ImGui into a GLFW application?

You need to include [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h), [`backends/imgui_impl_glfw.h`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_glfw.h), and [`backends/imgui_impl_opengl3.h`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_opengl3.h). Call `ImGui::CreateContext()`, then `ImGui_ImplGlfw_InitForOpenGL(window, true)` and `ImGui_ImplOpenGL3_Init(glsl_version)`. In your loop, call the respective `NewFrame()` functions, build your UI, call `ImGui::Render()`, and finally `ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData())`.

### Can I use ImGui with a custom engine that doesn't use standard backends?

Yes. The [`docs/BACKENDS.md`](https://github.com/ocornut/imgui/blob/main/docs/BACKENDS.md) file in the ocornut/imgui repository provides a template for creating custom backends. You implement functions to handle input events and render draw data (`ImDrawData`) using your engine's rendering API, using the standard backends in `backends/imgui_impl_*.cpp` as reference implementations.

### How do I enable docking and multi-viewport support in ImGui?

Set the configuration flags in your `ImGuiIO` structure after creating the context: `io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;` and `io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;`. The platform backend handles window creation, while the renderer backend must support the required flags for vertex offsets and textures.

### Which renderer backend offers the best performance for modern C++ applications?

**Vulkan** and **DirectX 12** offer the best performance for CPU-bound applications due to lower driver overhead and explicit control over command buffers. However, **OpenGL 3/4** remains sufficient for most tools and is easier to integrate with existing cross-platform C++ frameworks. The choice depends on your existing graphics infrastructure and performance requirements.