# How to Include Dear ImGui in a C++ Project: Complete Integration Guide

> Learn how to include Dear ImGui in your C++ project with our complete integration guide. Embed this powerful GUI library by adding source files and selecting backends for seamless development.

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

---

**Dear ImGui is a self-contained immediate-mode GUI library that you can embed into any C++ project by adding the core source files (`imgui*.h` and `imgui*.cpp`) to your build system and selecting appropriate platform and renderer backends from the `backends/` folder.**

Dear ImGui, maintained in the `ocornut/imgui` repository, is a bloat-free graphical user interface library designed for C++ developers who need fast, iterative UI tooling. Because the library carries **no external runtime dependencies**, you can include Dear ImGui in a C++ project by simply compiling the source files directly alongside your application code. This guide walks through the exact file structure, backend selection, and initialization sequence required for production-ready integration.

## Core Architecture and File Structure

Before integrating, it helps to understand how Dear ImGui separates concerns between the UI logic and system-specific implementation.

The library consists of three conceptual layers:

- **Core Library**: Provides the immediate-mode API (`ImGui::Begin()`, `ImGui::Button()`, etc.) and maintains UI state in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), [`imgui_draw.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_draw.cpp), [`imgui_tables.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_tables.cpp), and [`imgui_widgets.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_widgets.cpp). These files know nothing about how pixels reach the screen.

- **Platform Backend**: Bridges OS windowing and input events (mouse, keyboard, gamepad) into ImGui's internal format. Files like [`backends/imgui_impl_win32.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_win32.cpp) or [`backends/imgui_impl_glfw.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_glfw.cpp) handle window message loops and input polling.

- **Renderer Backend**: Translates ImGui's draw commands (`ImDrawData`) into GPU API calls. Implementations such as [`backends/imgui_impl_dx11.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_dx11.cpp) or [`backends/imgui_impl_opengl3.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_opengl3.cpp) upload vertex buffers and issue draw calls.

This architecture allows you to mix any platform backend with any renderer backend, enabling integration with virtually any existing engine or framework.

## Essential Files for Integration

To include Dear ImGui in a C++ project, add these files to your build system:

```text
imgui.h
imgui.cpp
imgui_draw.cpp
imgui_tables.cpp
imgui_widgets.cpp
imgui_demo.cpp       // Optional: contains ImGui::ShowDemoWindow()
imgui_internal.h     // Included by .cpp files, do not compile separately

```

The [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) header declares the public API, while the `.cpp` files implement the immediate-mode logic, widget rendering, and table systems. The [`imgui_demo.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_demo.cpp) file is optional but recommended for learning the API.

## Step-by-Step Integration Process

Follow these steps to integrate Dear ImGui into your existing C++ codebase.

### 1. Select and Add Backend Files

Choose one platform backend and one renderer backend based on your target OS and graphics API. For example:

- **Win32 + DirectX 11**: Add [`backends/imgui_impl_win32.h/.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_win32.h/.cpp) and [`backends/imgui_impl_dx11.h/.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_dx11.h/.cpp)
- **Cross-platform OpenGL**: Add [`backends/imgui_impl_glfw.h/.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_glfw.h/.cpp) and [`backends/imgui_impl_opengl3.h/.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_opengl3.h/.cpp)

Include both header and implementation files in your compiler's source list.

### 2. Initialize the ImGui Context

After creating your OS window and graphics device, create the ImGui context once:

```cpp
#include "imgui.h"
// ... include your selected backend headers

IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
ImGui::StyleColorsDark();  // or ImGui::StyleColorsLight();

```

`ImGui::CreateContext()` allocates the internal state structure, while `ImGui::GetIO()` exposes configuration flags and input/output references.

### 3. Initialize Platform and Renderer Backends

Call the initialization functions for your selected backends, passing native handles:

```cpp
// Win32 + DX11 example
ImGui_ImplWin32_Init(hwnd);                      // HWND from Windows API
ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);

```

For GLFW and OpenGL 3:

```cpp
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 130");

```

### 4. Implement the Per-Frame Loop

Inside your main loop, wrap your UI code with the following sequence:

```cpp
// Start the frame
ImGui_ImplDX11_NewFrame();      // or ImGui_ImplOpenGL3_NewFrame()
ImGui_ImplWin32_NewFrame();     // or ImGui_ImplGlfw_NewFrame()
ImGui::NewFrame();

// Build UI
ImGui::Begin("My Tool");
ImGui::Text("Application average %.3f ms/frame", 1000.0f / ImGui::GetIO().Framerate);
if (ImGui::Button("Save"))
    save_data();
ImGui::End();

// Finish the frame
ImGui::Render();
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());  // or OpenGL equivalent

```

This sequence mirrors the implementation in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), where `NewFrame()` prepares the draw list and `Render()` finalizes the `ImDrawData` structure for the backend.

### 5. Shutdown Cleanup

When closing your application, reverse the initialization order:

```cpp
ImGui_ImplDX11_Shutdown();      // or ImGui_ImplOpenGL3_Shutdown()
ImGui_ImplWin32_Shutdown();     // or ImGui_ImplGlfw_Shutdown()
ImGui::DestroyContext();

```

## Practical Implementation Examples

### Win32 and DirectX 11 Integration

This example demonstrates the minimal setup for a Windows desktop application:

```cpp
#include <d3d11.h>
#include <windows.h>
#include "imgui.h"
#include "backends/imgui_impl_win32.h"
#include "backends/imgui_impl_dx11.h"

// Global device pointers (initialize these in your D3D11 setup)
extern ID3D11Device*            g_pd3dDevice;
extern ID3D11DeviceContext*     g_pd3dDeviceContext;
extern HWND                     g_hWnd;
extern ID3D11RenderTargetView*  g_mainRenderTargetView;
extern IDXGISwapChain*          g_pSwapChain;

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    // ... Create window and initialize Direct3D 11 ...
    
    // Setup Dear ImGui
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO(); (void)io;
    ImGui::StyleColorsDark();
    
    // Setup Platform/Renderer backends
    ImGui_ImplWin32_Init(g_hWnd);
    ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);
    
    // Main loop
    bool done = false;
    while (!done)
    {
        // Poll and handle messages (input, resize, etc.)
        MSG msg;
        while (::PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE))
        {
            ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);
            if (msg.message == WM_QUIT)
                done = true;
        }
        if (done)
            break;
            
        // Start the Dear ImGui frame
        ImGui_ImplDX11_NewFrame();
        ImGui_ImplWin32_NewFrame();
        ImGui::NewFrame();
        
        // 2. Show a simple window
        static float f = 0.0f;
        static int counter = 0;
        ImGui::Begin("Hello, world!");
        ImGui::Text("This is some useful text.");
        ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
        if (ImGui::Button("Button"))
            counter++;
        ImGui::SameLine();
        ImGui::Text("counter = %d", counter);
        ImGui::End();
        
        // Rendering
        ImGui::Render();
        const float clear_color_with_alpha[4] = { 0.45f, 0.55f, 0.60f, 1.00f };
        g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, nullptr);
        g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha);
        ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
        
        g_pSwapChain->Present(1, 0); // Present with vsync
    }
    
    // Cleanup
    ImGui_ImplDX11_Shutdown();
    ImGui_ImplWin32_Shutdown();
    ImGui::DestroyContext();
    
    // ... Release Direct3D resources ...
    return 0;
}

```

### Cross-Platform GLFW and OpenGL 3 Setup

For Linux, macOS, or Windows with GLFW:

```cpp
#include "imgui.h"
#include "backends/imgui_impl_glfw.h"
#include "backends/imgui_impl_opengl3.h"
#include <GLFW/glfw3.h>

int main()
{
    // Setup GLFW
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
    GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+OpenGL3", nullptr, nullptr);
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1); // Enable vsync
    
    // Initialize OpenGL loader (gl3w, glew, or glad)
    // ...
    
    // Setup Dear ImGui context
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO(); (void)io;
    ImGui::StyleColorsClassic();
    
    // Setup Platform/Renderer backends
    ImGui_ImplGlfw_InitForOpenGL(window, true);
    ImGui_ImplOpenGL3_Init("#version 130");
    
    // Main loop
    while (!glfwWindowShouldClose(window))
    {
        glfwPollEvents();
        
        // Start the Dear ImGui frame
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();
        
        // UI Code
        ImGui::Begin("Cross-Platform Demo");
        ImGui::Text("Platform: GLFW");
        ImGui::Text("Renderer: OpenGL 3");
        static float value = 0.0f;
        ImGui::SliderFloat("Value", &value, 0.0f, 1.0f);
        ImGui::End();
        
        // Rendering
        ImGui::Render();
        int display_w, display_h;
        glfwGetFramebufferSize(window, &display_w, &display_h);
        glViewport(0, 0, display_w, display_h);
        glClearColor(0.45f, 0.55f, 0.60f, 1.00f);
        glClear(GL_COLOR_BUFFER_BIT);
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
        
        glfwSwapBuffers(window);
    }
    
    // Cleanup
    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();
    
    glfwDestroyWindow(window);
    glfwTerminate();
    
    return 0;
}

```

## Summary

- **Dear ImGui requires no external dependencies**—simply compile the core `.cpp` files ([`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), [`imgui_draw.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_draw.cpp), [`imgui_tables.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_tables.cpp), [`imgui_widgets.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_widgets.cpp)) directly into your project.
- **Select matching backends** from the `backends/` folder: one platform backend (Win32, GLFW, SDL2) and one renderer backend (DirectX, OpenGL, Vulkan) based on your existing infrastructure.
- **Follow the initialization sequence**: `CreateContext()` → backend `Init()` → per-frame `NewFrame()`/`Render()` → backend `Shutdown()` → `DestroyContext()`.
- **Include [`imgui_demo.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_demo.cpp)** to access `ImGui::ShowDemoWindow()`, which serves as interactive documentation for available widgets.

## Frequently Asked Questions

### What are the minimum files required to include Dear ImGui in a C++ project?

You need at minimum [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h), [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), [`imgui_draw.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_draw.cpp), [`imgui_tables.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_tables.cpp), and [`imgui_widgets.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_widgets.cpp) from the repository root, plus [`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/imgui_internal.h) which is included automatically. You must also add one platform backend pair (e.g., [`backends/imgui_impl_glfw.h/.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_glfw.h/.cpp)) and one renderer backend pair (e.g., [`backends/imgui_impl_opengl3.h/.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_opengl3.h/.cpp)) from the `backends/` folder to handle input and graphics API integration.

### Does Dear ImGui require external libraries or package managers?

No. Dear ImGui is designed as a single-header-library-style distribution with **no external runtime dependencies**. You do not need to link against system libraries beyond what your chosen backend requires (e.g., linking against `d3d11.lib` for DirectX 11 or `glfw` for windowing). The core library uses only the C++ standard library and OS headers.

### Can I use Dear ImGui with a custom game engine or existing codebase?

Yes. Because Dear ImGui generates a platform-agnostic draw list (`ImDrawData`) in [`imgui_draw.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_draw.cpp), you can integrate it with any engine by providing custom backends. If your engine uses a proprietary renderer, implement the `ImGui_ImplXXX_NewFrame()` and `ImGui_ImplXXX_RenderDrawData()` functions to translate ImGui's vertex buffers into your engine's draw calls, following the patterns in the official backend files.

### How do I handle keyboard and mouse input when including Dear ImGui?

Input handling is managed by the platform backend files in the `backends/` folder. Functions like `ImGui_ImplWin32_NewFrame()` or `ImGui_ImplGlfw_NewFrame()` poll the underlying windowing system and populate the `ImGuiIO` structure. In [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), the `NewFrame()` function uses this data to determine widget interactions. You can check `ImGui::GetIO().WantCaptureMouse` or `WantCaptureKeyboard` to determine if ImGui is consuming input events, allowing you to pass remaining events to your application logic.