dear-imgui-sys 0.16.0-alpha.2

Low-level FFI bindings to Dear ImGui v1.92.9b (docking branch) via cimgui (C API)
Documentation

dear-imgui-sys

Low-level Rust bindings for Dear ImGui via cimgui (C API) and checked-in pregenerated bindings.

Overview

This crate provides unsafe Rust bindings to Dear ImGui v1.92.9b (docking branch) using the cimgui C API. The core ig* API crosses a C ABI boundary. C++ backend integration and callback-bearing platform APIs use explicit repository-owned shims because their compiler ABI still matters, especially on MSVC.

Key Features

  • cimgui C API: A deliberate C boundary for the core ig* API
  • Docking Support: Full docking support; PlatformIO primitives for backend-specific native multi-viewport routes
  • Modern Dear ImGui: Based on Dear ImGui v1.92.9b docking branch
  • Cross-platform: Consistent builds on Windows (MSVC/MinGW), Linux, macOS, and WebAssembly
  • Prebuilt Binaries: Optional prebuilt static libraries for faster builds
  • Offline-friendly: Pregenerated bindings for normal builds, docs.rs, and offline environments
  • Optional backend shim ABI: Shared low-level self-contained backend shim modules for downstream backend crates and engine integrations
  • Optional stack layout artifact: The native-only stack-layout feature enables a patched core and repository-owned C ABI for blueprint-style layout helpers

Build Strategies

This crate supports multiple build strategies to fit different development workflows:

1. Prebuilt Static Libraries (Recommended)

The fastest way to get started is to use prebuilt static libraries instead of compiling from source. 0.16.0-alpha.1 archives are currently published. Until 0.16.0-alpha.2 is published, use a repository checkout or build the alpha.2 candidate from source.

# Option A: Point to the library directory inside an extracted core artifact.
# The strict manifest.txt may be in this directory or its parent artifact root.
export IMGUI_SYS_LIB_DIR=/path/to/extracted/dear-imgui-artifact/lib

# Option B: Use a package-tool-generated local archive or HTTP(S) URL.
export IMGUI_SYS_PREBUILT_URL=/path/to/dear-imgui-prebuilt-0.16.0-alpha.2-<target>-static.tar.gz
cargo build -p dear-imgui-sys --features prebuilt

# Option C: Enable HTTP(S) downloads / auto-download from GitHub releases
export IMGUI_SYS_USE_PREBUILT=1
cargo build -p dear-imgui-sys --features prebuilt

2. Build from Source

Compile Dear ImGui and cimgui from the vendored source code:

cargo build -p dear-imgui-sys

When building from a repository checkout, the vendored cimgui source comes from Git submodules. For a fresh checkout, clone with --recursive; for an existing checkout, run this inside the repository before building:

git submodule update --init --recursive

If Cargo reports a missing header such as dear-imgui-sys/third-party/cimgui/imgui/imgui.h, the cimgui submodule is not initialized.

Source builds use the cc crate on every platform. There is no alternate CMake core build route.

Normal source builds use the checked-in pregenerated Rust bindings and do not require libclang. Bindgen is only needed when regenerating bindings.

Requirements by platform:

  • Windows: Visual Studio Build Tools or Visual Studio with C++ support
    • Optional freetype source builds can use vcpkg: vcpkg install freetype:x64-windows-static-md
  • Linux: build-essential, pkg-config
    sudo apt-get install build-essential pkg-config
    
  • macOS: Xcode Command Line Tools
    xcode-select --install
    

When the freetype feature is enabled, dear-imgui-sys must find real FreeType development files. The build script tries pkg-config freetype2 first and vcpkg's freetype port next. On Windows/MSVC, install the vcpkg triplet that matches vcpkg-rs' selection, for example x64-windows-static-md for the default Rust CRT mode, or set VCPKGRS_TRIPLET explicitly. If you use a dynamic vcpkg triplet such as x64-windows, also set VCPKGRS_DYNAMIC=1.

3. Development Mode

Skip C/C++ compilation for faster Rust-only iteration:

export IMGUI_SYS_SKIP_CC=1
cargo build -p dear-imgui-sys

This uses pregenerated bindings and skips native compilation, useful when working on higher-level Rust code.

Offline Builds & docs.rs

This crate supports offline builds and docs.rs compilation through pregenerated bindings:

docs.rs Support

When building on docs.rs (DOCS_RS=1), the build script:

  • Selects the checked-in native ABI profile for the docs.rs target
  • Falls back to the same shared binding specification only when the profile file is unavailable and the bindgen feature is present
  • Skips native C/C++ compilation entirely

Updating Pregenerated Bindings

Core bindings are generated as Windows, non-Windows, and WASM profiles from one shared specification. To reproduce and compare all checked-in profiles:

cargo run -p xtask -- verify-bindings

After an intentional source or specification change, update all profiles and then verify them:

cargo run -p xtask -- verify-bindings --update --allow-dirty
python3 tools/update_submodule_and_bindings.py \
  --crates dear-imgui-sys --submodules auto --wasm

Canonical generation rejects BINDGEN_EXTRA_CLANG_ARGS*. The target profile, generator policy, header shims, enum normalization, formatter, and WASM provider all participate in the binding-spec hash.

WebAssembly Support

WebAssembly support for Dear ImGui in this workspace follows the same import-style design used by the high-level dear-imgui-rs crate:

  • Rust code links against a WASM import module named imgui-sys-v1 that provides the cimgui (C API) implementation.
  • The main application (Rust + winit + wgpu) targets wasm32-unknown-unknown and uses wasm-bindgen.
  • A separate provider module (imgui-sys-v1) is built once (currently via Emscripten) and contains Dear ImGui + cimgui and, optionally, selected extensions.

Provider ABI v1 includes the repository's checked numeric formatting and parsing source transform. Older v0 providers are not compatible and must be rebuilt; renaming or remapping a v0 artifact does not upgrade its semantics.

The wasm feature is mandatory for wasm32-unknown-unknown, the only supported WASM target. WASI (wasip1/wasip2) and Emscripten targets are rejected even with the feature because their runtime ABI cannot consume these import bindings. The provider name is fixed; generation commands do not accept an alternate import module. Enabling wasm on a native target is allowed and does not select the WASM binding profile.

End users typically interact with the flow indirectly through:

  • dear-imgui-rs with the wasm feature enabled.
  • The xtask commands (wasm-bindgen, web-demo, build-cimgui-provider) that wire the main module and provider together.

For a complete, up-to-date guide (including required tools, commands, and troubleshooting), see:

  • docs/WASM.md in this repository.
  • The examples-wasm crate (examples-wasm/dear-imgui-web-demo), which demonstrates the web demo setup.

Basic Usage

This is a low-level sys crate providing unsafe FFI bindings. Most users should use the higher-level dear-imgui-rs crate instead, which provides safe Rust wrappers.

Until 0.16.0-alpha.2 is published, test this candidate from main:

[dependencies]
dear-imgui-sys = { git = "https://github.com/Latias94/dear-imgui-rs", branch = "main" }

After publication, use the exact prerelease requirement:

[dependencies]
dear-imgui-sys = "=0.16.0-alpha.2"

# Enable features as needed
dear-imgui-sys = { version = "=0.16.0-alpha.2", features = ["freetype", "wasm"] }

Direct FFI Usage (Advanced)

use dear_imgui_sys::*;

unsafe {
    let ctx = igCreateContext(std::ptr::null_mut());
    igSetCurrentContext(ctx);

    // Configure ImGui...
    let io = igGetIO();
    (*io).DisplaySize = ImVec2 { x: 800.0, y: 600.0 };

    // Main loop
    igNewFrame();
    igText(b"Hello from Dear ImGui!\0".as_ptr() as *const std::os::raw::c_char);
    igRender();

    // Clean up
    igDestroyContext(ctx);
}

Backend Shim Features (Advanced)

For backend crates, engine integrations, and low-level users, dear-imgui-sys can expose optional backend shim modules behind backend-shim-* features:

[dependencies]
dear-imgui-sys = { version = "=0.16.0-alpha.2", features = ["backend-shim-opengl3"] }

These features expose self-contained modules such as:

  • dear_imgui_sys::backend_shim::win32
  • dear_imgui_sys::backend_shim::dx11
  • dear_imgui_sys::backend_shim::android
  • dear_imgui_sys::backend_shim::opengl3

SDLRenderer3 and SDLGPU3 renderer shims are owned by dear-imgui-sdl3, not dear-imgui-sys. Use dear-imgui-sdl3 with feature sdlrenderer3-renderer or sdlgpu3-renderer for those renderer integrations.

Important scope note:

  • backend-shim-* exposes the repository-owned C shim ABI, not the original upstream C++ backend symbol names
  • self-contained official backends may be compiled by dear-imgui-sys behind these features
  • SDL3 renderer shims are framework-specific and are compiled by dear-imgui-sdl3
  • this does not mean dear-imgui-rs already provides a safe wrapper for those backends

Why Shim ABI Matters

The core ig* API comes from cimgui, so it is a normal C ABI boundary.

The official Dear ImGui backend entry points (imgui_impl_win32.cpp, imgui_impl_dx11.cpp, imgui_impl_opengl3.cpp, etc.) are different:

  • they are implemented as C++ backend code
  • their upstream symbol names are not the portable Rust-facing ABI
  • Rust should call a deliberate C shim boundary instead

dear-imgui-sys therefore exposes a backend shim ABI for self-contained official backends instead of pretending the upstream imgui_impl_* names are a stable C interface.

Typical Downstream Pattern

There are two supported low-level patterns.

  1. For self-contained official backends such as opengl3, android, win32, and dx11, enable the matching backend-shim-* feature and call the shim module directly from Rust.
  2. For framework-specific integrations such as SDL3, keep the framework build logic in the backend crate, optionally reuse upstream backend sources exported by dear-imgui-sys, and define crate-local wrappers where needed.

dear-imgui-sys exports both upstream backend sources and repository-owned shim sources to dependents as cargo metadata:

// build.rs
use std::env;
use std::path::PathBuf;

let imgui_backends = PathBuf::from(
    env::var("DEP_DEAR_IMGUI_IMGUI_BACKENDS_PATH")
        .expect("dear-imgui-sys did not export IMGUI_BACKENDS_PATH"),
);
let backend_shims = PathBuf::from(
    env::var("DEP_DEAR_IMGUI_IMGUI_BACKEND_SHIMS_PATH")
        .expect("dear-imgui-sys did not export IMGUI_BACKEND_SHIMS_PATH"),
);
let imgui_root = imgui_backends
    .parent()
    .expect("IMGUI_BACKENDS_PATH should point to imgui/backends");

This remains useful for backend crates such as dear-imgui-sdl3, which still own SDL3-specific build logic even though dear-imgui-sys now provides shared shims for self-contained backends such as OpenGL3.

Stack Layout Compatibility Shim

With feature stack-layout, dear-imgui-sys builds a repository-owned stack layout shim that backs the safe dear-imgui-rs helpers named begin_horizontal, begin_vertical, and spring.

cargo build -p dear-imgui-sys --features stack-layout

Scope notes:

  • Dear ImGui itself does not ship BeginHorizontal, BeginVertical, or Spring as official public APIs.
  • The shim is provided so Rust examples can follow the blueprint-style imgui-node-editor examples without patching the Dear ImGui submodule.
  • Native source builds patch only the generated OUT_DIR copy of imgui.cpp to add the ItemSize() / ItemAdd() hooks that the upstream stack layout extension needs for regular ImGui widgets to be measured correctly.
  • The implementation is derived from the MIT-licensed stack layout extension vendored by imgui-node-editor; see THIRD_PARTY_NOTICES.md.
  • The Rust-facing ABI uses dear_imgui_stack_* symbols and is owned by this crate. Downstream code should prefer the safe dear-imgui-rs wrappers.
  • Normal native builds compile the original Dear ImGui core and do not export the shim symbols.
  • Official release prebuilt profiles match exactly: stack-layout artifacts use a -stack-layout archive suffix, or -stack-layout-freetype when FreeType is also enabled. Their manifests declare the same feature set, so neither can substitute for a normal or FreeType-only artifact.
  • stack-layout is native-only and cannot be combined with the WASM feature or target.

Cargo Metadata for Backend Authors

Backend and engine integration crates can consume these cargo metadata exports from dear-imgui-sys:

  • DEP_DEAR_IMGUI_IMGUI_INCLUDE_PATH: upstream Dear ImGui include root
  • DEP_DEAR_IMGUI_IMGUI_BACKENDS_PATH: upstream imgui/backends directory
  • DEP_DEAR_IMGUI_CIMGUI_INCLUDE_PATH: cimgui include root
  • DEP_DEAR_IMGUI_IMGUI_BACKEND_SHIMS_PATH: repository-owned backend-shims directory

Preferred use:

  • use the Rust backend_shim::* modules directly when dear-imgui-sys already provides the low-level ABI you need
  • use IMGUI_BACKENDS_PATH when your crate still owns framework-specific compilation such as SDL3/GLFW glue
  • use IMGUI_BACKEND_SHIMS_PATH only when you intentionally need access to the repository-owned shim sources from a downstream build script

Android Integration Recipes

There are two first-class Android directions.

  1. Custom Android backend without a dedicated first-party crate yet:

    [dependencies]
    dear-imgui-rs = "=0.16.0-alpha.2"
    dear-imgui-sys = { version = "=0.16.0-alpha.2", features = ["backend-shim-android", "backend-shim-opengl3"] }
    

    Use dear-imgui-rs for the safe core (Context, IO, frame lifecycle, textures, render snapshots) and call dear_imgui_sys::backend_shim::{android, opengl3} for the low-level official backend pieces.

    A concrete repository template for this route lives at examples-android/dear-imgui-android-smoke/. It is intentionally kept outside the main workspace build so we can document and validate the Android path without changing the normal desktop/web CI matrix.

    The repository currently uses this template as the concrete proof that the low-level Android route is viable before any dedicated first-party Android convenience crate exists: it is cross-compiled in isolation, carries the minimal cargo-apk2 metadata needed to build a NativeActivity APK without introducing a new published crate, and now also owns a minimal EGL / GLES3 render loop that renders actual Dear ImGui UI on-device.

    Important nuance: if your Android app uses android-activity, its input API wraps raw AInputEvent* values. In that setup you will typically translate input into dear-imgui-rs::Io manually, or choose a lower-level glue path that gives direct access to raw Android input events before delegating to backend_shim::android.

  2. SDL3-based Android integration:

    Depend on dear-imgui-sdl3 for the SDL3 backend wrapper, but keep SDL3 acquisition, NDK setup, and Android packaging owned by the application. The application may provide SDL3 headers via SDL3_INCLUDE_DIR, rely on pkg-config/vcpkg discovery, or add a direct sdl3 dependency with features = ["build-from-source"] so Cargo feature unification makes sdl3-sys export DEP_SDL3_OUT_DIR. When using the build-from-source route, the application still needs to provide the Android ABI/toolchain contract expected by SDL3's CMake build (ANDROID_ABI / CMAKE_ANDROID_ARCH_ABI, toolchain file, generator, etc.), typically via cargo-ndk, Gradle+CMake, or an equivalent app-owned build system.

This is the intended ownership split: dear-imgui-sys owns reusable low-level building blocks; framework- and application-specific Android integration remains outside the core crates.

Technical Details

cimgui Integration

This crate uses cimgui as the C API layer:

  • Core C ABI: cimgui exposes the core ig* calls through C; backend shims and callback signatures retain explicit platform/compiler ABI contracts
  • Complete API Coverage: All Dear ImGui functions are available through the C API
  • Consistent Naming: Functions follow the ig* naming convention (e.g., igText, igButton)
  • Pregenerated by default: Checked-in bindings are copied into OUT_DIR for normal builds
  • Explicit regeneration: Set DEAR_IMGUI_RS_REGEN_BINDINGS=1 to run bindgen from cimgui headers

Two native binding files are selected by target facts rather than by the host that published the crate:

  • bindings_pregenerated_windows.rs for supported 64-bit Windows MSVC/GNU ABIs
  • bindings_pregenerated.rs for supported Linux, Android, macOS, and iOS ABIs

WASM uses wasm_bindings_pregenerated.rs and imports the fixed imgui-sys-v1 provider. ImGuiDockNode is intentionally opaque and pointer-only; C/C++ va_list APIs are omitted because neither has one portable Rust layout.

The packaged Cargo manifest records exact cimgui and nested Dear ImGui revisions under [package.metadata.dear-imgui-sources]. Builds and artifact packaging use that metadata without requiring a .git directory. Update and release checks require both source submodules to be clean and to match the recorded revisions.

Version Information

  • Dear ImGui Version: v1.92.9b (docking branch)
  • cimgui Version: Pinned to a revision generated against Dear ImGui v1.92.9b
  • Supported Features: Docking, FreeType font rendering, and low-level PlatformIO/multi-viewport primitives; end-to-end status is documented per backend route

Environment Variables

Control build behavior with these environment variables:

Variable Description
IMGUI_SYS_LIB_DIR Directory containing the core static library; a matching strict manifest.txt must be in that directory or its parent
IMGUI_SYS_PREBUILT_URL Local path or direct URL to a package-tool-generated core archive; HTTP(S) and .tar.gz extraction require feature prebuilt
IMGUI_SYS_USE_PREBUILT Enable automatic download from GitHub releases (1, requires feature prebuilt)
IMGUI_SYS_SKIP_CC Skip C/C++ compilation, use pregenerated bindings only (1)
IMGUI_SYS_FORCE_BUILD Force build from source, ignore prebuilt options (1)
DEAR_IMGUI_RS_REGEN_BINDINGS Regenerate Rust bindings with bindgen (1; requires --features bindgen and libclang)

Bare .a/.lib inputs are not trusted core artifacts. An explicit library is accepted only when its directory or parent artifact root also contains the complete matching manifest.txt; using the packaged .tar.gz is recommended.

Related Crates

This crate is part of the dear-imgui-rs ecosystem:

License

Licensed under either of:

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.