# Dear ImGui Platform Backends Compared: GLFW vs SDL2 vs SDL3 vs Win32

> Compare Dear ImGui platform backends: GLFW, SDL2, SDL3, and Win32. Understand their OS support, input handling, and multi-viewport differences to choose the best fit for your project.

- Repository: [omar/imgui](https://github.com/ocornut/imgui)
- Tags: deep-dive
- Published: 2026-07-25

---

**The four primary Dear ImGui platform backends—GLFW, SDL2, SDL3, and Win32—all implement the same ImGuiIO contract but vary in OS support, input handling patterns, and multi-viewport capabilities, with GLFW offering the lightest cross-platform footprint, SDL2/3 providing extensive mobile support, and Win32 delivering the most robust native Windows integration.**

Dear ImGui (ocornut/imgui) maintains a strict separation between platform logic (windowing, input, clipboard) and rendering concerns. The `backends/` directory contains reference implementations that bridge ImGui's abstract **ImGuiIO** interface with concrete operating system APIs. Selecting the appropriate **Dear ImGui platform backend** for your application requires evaluating dependency constraints, target platforms, and specific feature requirements such as multi-viewport support or gamepad integration.

## Architecture and Common Interface

All platform backends in the Dear ImGui repository adhere to a standardized initialization and frame lifecycle. Regardless of whether you choose **GLFW**, **SDL2**, **SDL3**, or **Win32**, the public API surface remains consistent:

```cpp
bool ImGui_ImplXXXX_InitForOpenGL(...);
bool ImGui_ImplXXXX_InitForVulkan(...);
void ImGui_ImplXXXX_Shutdown();
void ImGui_ImplGlfw_NewFrame();  // or ImGui_ImplSDL2_NewFrame, etc.

```

During initialization, each backend populates `io.BackendPlatformUserData` with a pointer to private data, sets `io.BackendPlatformName` (e.g., `"imgui_impl_glfw"`), and configures `io.BackendFlags` to advertise supported features such as `ImGuiBackendFlags_HasMouseCursors`, `HasGamepad`, or `PlatformHasViewports` according to the implementation in `backends/imgui_impl_*.cpp`. This design enables you to pair any platform backend with any renderer backend (OpenGL, Vulkan, DirectX, Metal) without modifying your rendering code.

## Input Handling Patterns

The primary architectural difference between backends lies in event processing. **GLFW** ([`backends/imgui_impl_glfw.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_glfw.cpp)) relies on callback installation via `ImGui_ImplGlfw_InstallCallbacks`, which forwards GLFW events to ImGui while preserving user callbacks. Alternatively, you can set `install_callbacks=false` during initialization and call backend functions manually.

**SDL2** ([`backends/imgui_impl_sdl2.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_sdl2.cpp)) and **SDL3** ([`backends/imgui_impl_sdl3.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_sdl3.cpp)) require you to pump events through `ImGui_ImplSDL2_ProcessEvent(const SDL_Event*)` or `ImGui_ImplSDL3_ProcessEvent`, typically called within your main `SDL_PollEvent` loop. This explicit approach gives you full control over event filtering before ImGui sees them.

**Win32** ([`backends/imgui_impl_win32.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_win32.cpp)) expects you to forward window messages to `ImGui_ImplWin32_WndProcHandler(hwnd, msg, wParam, lParam)` inside your window procedure. This handler translates `WM_KEYDOWN`, `WM_MOUSEMOVE`, and other Windows messages into ImGui IO calls.

## Backend-Specific Capabilities

### GLFW Backend

The **GLFW** backend ([`backends/imgui_impl_glfw.h`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_glfw.h) and [`imgui_impl_glfw.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_glfw.cpp)) provides the most straightforward cross-platform solution. It supports Windows, macOS, and Linux through the GLFW library, with zero mobile platform support.

**Key characteristics:**
- **Dependencies:** Only requires linking against GLFW.
- **Multi-viewport:** Supports `ImGuiBackendFlags_PlatformHasViewports` for creating secondary GLFW windows.
- **DPI Awareness:** Exposes `ImGui_ImplGlfw_GetContentScaleForWindow` and `ImGui_ImplGlfw_GetContentScaleForMonitor` for high-DPI handling.
- **Input:** Converts `GLFW_KEY_*` scancodes to `ImGuiKey` values (legacy keycodes removed since v1.87).
- **Gamepad:** Reads joystick state via `glfwGetJoystickAxes` and `glfwGetJoystickButtons` when `ImGuiBackendFlags_HasGamepad` is set.

### SDL2 Backend

The **SDL2** backend ([`backends/imgui_impl_sdl2.h`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_sdl2.h) and [`imgui_impl_sdl2.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_sdl2.cpp)) targets SDL 2.0.14 and above, offering broad platform coverage including iOS and Android.

**Key characteristics:**
- **Event Processing:** Uses `ImGui_ImplSDL2_ProcessEvent` to wrap `SDL_PollEvent` data.
- **IME Support:** Automatically calls `SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1")` before window creation and forwards `SDL_TEXTINPUT` events for proper international text input.
- **Gamepad:** Integrates with `SDL_GameController` for structured gamepad input.
- **Multi-viewport:** Available on SDL 2.0.14+, though less robust than Win32 or SDL3 implementations.
- **Scaling:** Provides `ImGui_ImplSDL2_GetContentScaleForWindow` and `ImGui_ImplSDL2_GetContentScaleForDisplay`.

### SDL3 Backend

The **SDL3** backend ([`backends/imgui_impl_sdl3.h`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_sdl3.h) and [`backends/imgui_impl_sdl3.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_sdl3.cpp)) updates the SDL2 implementation for the newer SDL 3 API, maintaining the same feature set with architectural improvements.

**Key characteristics:**
- **API Modernization:** Uses SDL3's unified event system and improved multi-window support.
- **Gamepad:** Transitions to `SDL_Gamepad` from the legacy `SDL_GameController`.
- **IME:** Benefits from SDL3's improved Input Method Editor handling compared to SDL2.
- **Migration:** Requires updating function calls to SDL3 conventions (e.g., `SDL_Init` flags and window creation parameters).

### Win32 Backend

The **Win32** backend ([`backends/imgui_impl_win32.h`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_win32.h) and [`backends/imgui_impl_win32.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_win32.cpp)) offers native Windows integration without external dependencies beyond the Windows SDK.

**Key characteristics:**
- **Platform Exclusivity:** Windows only, but provides the most robust **multi-viewport** implementation via direct `CreateWindowEx` calls.
- **Message Handling:** Implements `ImGui_ImplWin32_WndProcHandler` to process `WM_*` messages including `WM_KEYDOWN`, `WM_MOUSEMOVE`, and `WM_IME_COMPOSITION`.
- **DPI Scaling:** Exposes `ImGui_ImplWin32_GetDpiScaleForHwnd` and `ImGui_ImplWin32_GetDpiScaleForMonitor` for per-monitor DPI awareness.
- **Cursor Management:** Uses native `SetCursor` and `LoadCursor` APIs with `ImGuiBackendFlags_HasMouseCursors`.
- **Alpha Compositing:** Supports optional transparent window features not available in other backends.

## Implementation Examples

### GLFW Integration

Link against GLFW and include the backend files:

```cpp
// Setup
GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui + GLFW", nullptr, nullptr);
glfwMakeContextCurrent(window);

IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();

ImGui_ImplGlfw_InitForOpenGL(window, true);  // true = install callbacks
ImGui_ImplOpenGL3_Init("#version 130");

// Main loop
while (!glfwWindowShouldClose(window))
{
    glfwPollEvents();  // Callbacks automatically update ImGui
    
    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();
    
    // Your UI code here
    
    ImGui::Render();
    // Rendering...
}

```

### SDL2 Event Loop

Explicit event forwarding requires calling `ImGui_ImplSDL2_ProcessEvent`:

```cpp
// Initialization
SDL_Window* window = SDL_CreateWindow("Dear ImGui + SDL2", 
    SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, 
    SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);

ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
ImGui_ImplOpenGL3_Init("#version 130");

// Event loop
bool done = false;
while (!done)
{
    SDL_Event event;
    while (SDL_PollEvent(&event))
    {
        ImGui_ImplSDL2_ProcessEvent(&event);  // Forward to ImGui
        if (event.type == SDL_QUIT)
            done = true;
    }
    
    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplSDL2_NewFrame();
    ImGui::NewFrame();
    // Rendering...
}

```

### Win32 Message Processing

Forward Windows messages to the backend handler:

```cpp
// In your WndProc or message loop
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
        return true;  // ImGui consumed this message
    
    // Your application handling...
    return DefWindowProc(hWnd, msg, wParam, lParam);
}

// Initialization
ImGui_ImplWin32_Init(hwnd);
ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);

```

## Summary

- **GLFW** ([`backends/imgui_impl_glfw.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_glfw.cpp)) provides the lightest cross-platform solution for desktop applications using OpenGL or Vulkan, with simple callback-based input.
- **SDL2** ([`backends/imgui_impl_sdl2.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_sdl2.cpp)) offers mature mobile support (iOS/Android) and explicit event processing via `ImGui_ImplSDL2_ProcessEvent`.
- **SDL3** ([`backends/imgui_impl_sdl3.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_sdl3.cpp)) delivers the same coverage as SDL2 with a modernized API, improved multi-window support, and better IME handling.
- **Win32** ([`backends/imgui_impl_win32.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_win32.cpp)) requires no external libraries and enables the most advanced multi-viewport features on Windows through native message handling.

## Frequently Asked Questions

### Can I use GLFW for the platform backend and DirectX 11 for rendering?

Yes. Dear ImGui decouples platform and renderer backends entirely. You can call `ImGui_ImplGlfw_InitForOpenGL` (or `InitForVulkan`, `InitForOther`) to initialize GLFW for windowing and input, then pair it with `ImGui_ImplDX11_Init` for rendering. The platform backend only updates `ImGuiIO` fields like `MousePos` and `DisplaySize`, while the renderer backend handles `ImDrawData` output.

### Why does the Win32 backend offer better multi-viewport support than SDL2?

The **Win32** backend creates native Windows via direct `CreateWindowEx` calls and manages them through the standard Windows message loop, giving it full control over window borders, alpha channels, and DPI scaling. **SDL2** (prior to 2.0.14) lacked robust multi-window API support, and even modern versions abstract window management, which can limit certain platform-specific optimizations that Dear ImGui's multi-viewport system requires for floating tool windows.

### How do I disable automatic mouse cursor changes in GLFW or SDL?

Set the `ImGuiConfigFlags_NoMouseCursorChange` flag in your `ImGuiIO` configuration before calling the backend's `NewFrame` function:

```cpp
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange;

```

This prevents the **GLFW** backend from calling `glfwSetCursor`, the **SDL** backends from calling `SDL_SetCursor`, and the **Win32** backend from calling `SetCursor`, allowing your application to manage cursor shapes manually.

### What is the minimum SDL version required for multi-viewport support?

**SDL2** requires version 2.0.14 or later for `ImGuiBackendFlags_PlatformHasViewports` support, as earlier versions lack the necessary window management APIs. **SDL3** supports multi-viewport natively without version constraints. If you target older SDL2 releases, you must disable the viewport feature flag to prevent runtime errors.