# Dear ImGui Bundle: the book, in plain text
The pages of the book for users (https://imgui-bundle.pages.dev/doc/), one after the other: what the bundle is, how to install it, the core libraries, the add-ons, the notes for Python and for C++. Each page starts with its URL. The pictures are left out, and so are the developer docs (how to build the bundle and its bindings).
The guide for AI assistants: https://imgui-bundle.pages.dev/llms.txt
The API, in plain text: https://imgui-bundle.pages.dev/llms/api/index.txt
The demos, with their code: https://imgui-bundle.pages.dev/llms/demos.txt
--------------------------------------------------------------------------------
Page: https://imgui-bundle.pages.dev/doc/intro/what-is-imgui-bundle/
# What is Dear ImGui Bundle?
Dear ImGui Bundle is a "batteries included" framework built on [Dear ImGui](https://github.com/ocornut/imgui). It bundles 20+ libraries for plotting, markdown, node editors, 3D gizmos, and more - all working seamlessly in **C++ and Python**, on **all major platforms** (Windows, Linux, macOS, iOS, Android, WebAssembly).
If you are building scientific tools, game tools, visualization applications, developer tools, or creative apps, give it a try.
You'll soon see that GUI code can be clear, readable, and easy to maintain. The immediate mode paradigm makes it a joy to reason about your app logic.
**Key highlights:**
- **Immediate mode**: Your code reads like a book. No widget trees, no callbacks, no synchronization headaches.
- **Cross-platform**: Same code runs on desktop, mobile, and web (via Emscripten or Pyodide).
- **Python-first**: Full Python bindings with type hints and IDE autocompletion.
- **Always up-to-date**: Tracks Dear ImGui upstream closely; Python bindings are auto-generated.
---
## Code That Reads Like a Book
The immediate mode paradigm means your UI code is simple and direct: the app below can be coded with just 9 readable lines of Python:
```python
from imgui_bundle import imgui, hello_imgui
selected_idx = 0
items = ["Apple", "Banana", "Cherry"]
def gui():
global selected_idx
imgui.text("Choose a fruit:")
_, selected_idx = imgui.list_box("##fruits", selected_idx, items)
imgui.text(f"You selected: {items[selected_idx]}")
hello_imgui.run(gui, window_title="Fruit Picker")
```
The relation between code and behavior is direct: what you write is what runs. There are no hidden widget trees, no callback chains, and no implicit state synchronization. This makes it easier to reason about your app's logic and flow.
**Easy to understand for humans**
Being able to work with readable code is getting more and more important as LLMs are now widely used to generate code: *You*, the human, still need to understand, review, and maintain that code. Immediate mode makes this easier.
**Easy to understand for AI**
And the same clarity that helps humans also helps AI: with no implicit state to get wrong, LLMs can read and generate ImGui code reliably. The [full PDF manuals](https://imgui-bundle.pages.dev/doc/assets/imgui_bundle_book.pdf) give an AI assistant all the context it needs.
Tip:
**Try it in your browser — no install needed:** [Open the Online Python Playground](https://imgui-bundle.pages.dev/playground/)
---
## Who is it for?
- **beginners and developers**: go from idea to GUI prototype in minutes, without learning a complex framework. Deploy to almost any platform.
- **ML/AI researchers**: visualize training in real time, tune hyperparameters mid-run, inside Jupyter
- **Computer vision engineers**: inspect images and tensors at the pixel level with ImmVision
- **Robotics developers**: fast, readable debug UIs in Python or C++
- **Scientific instrument builders**: cross-platform GUIs that deploy to desktop and web from the same code
- **Technical tool makers**: build node editors, gizmos, code editors without a web stack
- **Teachers and science communicators**: interactive lessons that open from a link, on a computer or a phone, such as [Grokking](https://imgui-bundle.pages.dev/playground/?demo=explorables/grokking/grokking.py) or the [logistic map](https://imgui-bundle.pages.dev/playground/?demo=explorables/logistic_map.py)
**Who is this project not for**
You should prefer a more complete framework (such as Qt for example) if your intent is to build a fully fledged application, with support for accessibility, internationalization, or the platform's native look. The style itself is not the limit: 17 themes, tweaked live, though not with CSS.
Its strength lies elsewhere: the same code runs on the desktop, in the browser and on phones, in C++ as in Python, and it is fast. Qt comes closest, but its Python does not run in the browser.
---
## Learn More
- **[Key Features](https://imgui-bundle.pages.dev/doc/intro/key-features/)** — Library list, FAQ, and more details.
- **[Immediate Mode Explained](https://imgui-bundle.pages.dev/doc/intro/imm-gui/)** — Understand the paradigm that makes ImGui different.
- **[Interactive Manuals & Demos](https://imgui-bundle.pages.dev/doc/intro/interactive-manuals/)** — Try the demos in your browser.
- **[Hello ImGui and ImmApp](https://imgui-bundle.pages.dev/doc/core-libs/hello-imgui-immapp/)** — High-level runners that take care of the app loop, windowing, and assets management, so that you can start an app with a single line of code.
- **[Jupyter Notebooks](https://imgui-bundle.pages.dev/doc/python/notebook-runners/)** — Interactive GUIs inside Jupyter. Your training loop keeps running while you tune hyperparameters.
--------------------------------------------------------------------------------
Page: https://imgui-bundle.pages.dev/doc/intro/key-features/
# Key Features
## Works everywhere
* **Cross-platform in C++ and Python:** Works on Windows, Linux, macOS, iOS, Android, and WebAssembly!
* **Web ready**: Develop full web applications, in C++ via Emscripten; or in Python thanks to ImGui Bundle's integration within Pyodide.
## First class support for Python
* **Python Bindings:** Using Dear ImGui Bundle in Python is extremely easy and productive.
* **Well documented Python bindings and stubs:** The Python bindings stubs reflect the C++ API and documentation, serving as a reference and aiding autocompletion in your IDE. See for example the [stubs for imgui](https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/imgui/__init__.pyi), and [for hello_imgui](https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/hello_imgui.pyi).
* Use it to create **standalone apps** (on Windows, macOS, and Linux), or to add **interactive UIs to your notebooks**. Deploy your apps **on the web** with ease, using [Pyodide](https://pyodide.org/en/stable/).
## Easy to use & well documented
* The Immediate Mode GUI (IMGUI) paradigm is simple and powerful, letting you focus on the creative aspects of your projects.
* **Easy to use, yet very powerful:** Start your first app in 3 lines.
* **Interactive Demos and Documentation:** Quickly get started with the ImGui Bundle Interactive Explorer, that showcases the capabilities of the pack. Read or copy-paste the source code (Python and C++) directly from there!
## Always up-to-date
* **Auto-generated bindings:** Python bindings are automatically generated, ensuring they stay synchronized with C++ APIs.
* **Version tracking:** ImGui Bundle version numbers match Dear ImGui releases (e.g., ImGui Bundle 1.91.x includes Dear ImGui 1.91.x). Updates typically follow within days of upstream releases.
## High performance
* **Fast:** Rendering is done via OpenGL (or any other renderer you choose), through native code.
# Comprehensive Library Integration
Dear ImGui Bundle isn't just ImGui - it's a curated ecosystem with more than 20 integrated libraries, where
Each library is:
- Available in Python and C++ with consistent APIs
- Always up to date, since Python bindings are autogenerated
- Documented with interactive examples
### Core Libraries
* Dear ImGui : Bloat-free Graphical User interface with minimal dependencies
* ImGui Test Engine : Dear ImGui Tests & Automation Engine
* Hello ImGui : cross-platform Gui apps with the simplicity of a "Hello World" app
### Plotting & Visualization
* ImPlot : Immediate Mode Plotting
* ImPlot3D : Immediate Mode 3D Plotting
* ImmVision : Immediate image debugger and insights
* imgui_tex_inspect : A texture inspector tool for Dear ImGui
### Text Editing & Markdown
* ImGuiColorTextEdit : Colorizing text editor for ImGui
* imgui_rich_md : Markdown renderer for Dear ImGui using the MD4C parser, with LaTeX math and syntax-highlighted code blocks (based on imgui_md)
### Tools
* ImGuizmo : Immediate mode 3D gizmo for scene editing
* imgui-node-editor : Node Editor built using Dear ImGui
* NanoVG : Antialiased 2D vector drawing library on top of OpenGL
### Widgets
* ImFileDialog : A file dialog library for Dear ImGui
* portable-file-dialogs : _OS native_ file dialogs library (C++11, single-header)
* imgui-knobs : Knobs widgets for ImGui
* imspinner : Set of nice spinners for imgui
* imgui_toggle : A toggle switch widget for Dear ImGui
* ImCoolBar : A Cool bar for Dear ImGui
* imgui-command-palette : A Sublime Text or VSCode style command palette in ImGui
# Common Questions
## Is it up to date?
**Yes!** Because: Python bindings are auto-generated, so they stay in sync with C++
## "Isn't rebuilding the UI every frame slow?"
**No!** Because:
- Widget calls are cheap (just generate drawing commands)
- Actual rendering is GPU-accelerated
- Typical frame times: < 1ms for most UIs
- Easily achieves 60+ FPS even with complex interfaces
## "How's the Python performance?"
**Excellent!** Because:
- Each widget call crosses to C++ once per frame
- Heavy lifting (rendering) is in C++
- Python overhead is < 0.5ms per frame typically
- Real bottleneck is usually your application logic, not the GUI
## "Does it work on the web?"
**Yes, impressively!**
- C++ → Emscripten → WebAssembly
- Python → Pyodide → WebAssembly (!!)
- Full Python runtime in browser
- Native-speed rendering via WebGL
- Check [ImGui Bundle Explorer](https://imgui-bundle.pages.dev/explorer/)
## Is It Interesting for Developers?
**Absolutely yes**, for several reasons:
* The immediate-mode paradigm is genuinely refreshing: your code directly expresses intent
* Rapid Development: From zero to functional UI is remarkably fast:
* The cross-platform support actually works: the same code runs on Windows, macOS, Linux. Mobile support is real (in C++), and web support via Emscripten and Pyodide also.
* Active Community: Dear ImGui itself has 70k+ stars. Dear ImGui Bundle adds comprehensive Python support, and has 1k+ stars (growing steadily).
--------------------------------------------------------------------------------
Page: https://imgui-bundle.pages.dev/doc/intro/imm-gui/
# Immediate GUI
# What is an Immediate GUI
An "Immediate Mode Graphical User Interface" lets you build user interfaces directly in code.
This keeps the UI and app state in perfect sync with minimal boilerplate. This approach is especially popular for quick prototyping and tools because it's intuitive, flexible, easy to maintain, and trivial to debug.
The example below shows a documented example to explain the Immediate Mode GUI paradigm:
Python:
```python
from imgui_bundle import imgui, immapp
counter = 0 # our app state
# The gui() function is called every frame, so the UI updates in real time.
def gui():
global counter
# The state of the UI is always in sync with the app state,
# via standard variables: debugging UI becomes trivial!
imgui.text(f"Counter ={counter}")
# We can display a button, and handle its action in one line:
if imgui.button("increment counter"):
counter += 1
# Below, we can also set the counter value via a slider between 0 and 100
value_changed, counter = imgui.slider_int("Set counter", counter, 0, 100)
# Run the app (in one line!)
immapp.run(gui)
```
C++:
```cpp
#include "immapp/immapp.h"
#include "imgui.h"
int counter = 0; // our app state
// The gui() function is called every frame, so the UI updates in real time.
void gui()
{
// The state of the UI is always in sync with the app state,
// via standard variables: debugging UI becomes trivial!
ImGui::Text("Counter =%d", counter);
// We can display a button, and handle its action in one line:
if (ImGui::Button("increment counter"))
counter += 1;
// Below, we can also set the counter value via a slider between 0 and 100
ImGui::SliderInt("Set counter", &counter, 0, 100);
}
// Run the app (in one line!)
int main(int, char **) { ImmApp::Run(gui); }
```
It produces this simple app:
**Immediate Mode GUI does not mean that you cannot separate concerns!**
You can still (and should) maintain a separate application state. The key difference is that your GUI can interact directly with that state in a straightforward way, without the need to maintain a separate UI state or complex event handling systems.
# Dear ImGui
The most popular Immediate Mode GUI library is [Dear ImGui](https://github.com/ocornut/imgui), a powerful **C++** library originally created for real-time tools in game engines, now widely used in many industries, with over 60k stars on GitHub.
Dear ImGui Bundle includes Dear ImGui plus many extra libraries, making it ideal for rapid prototyping as well as building complex apps with advanced widgets, plotting, node editors; in C++ and Python.
# Get started in no time with Hello ImGui and ImmApp
With Hello ImGui and ImmApp (both included in Dear ImGui Bundle), you can create a full-featured GUI application with just a few lines of code.
* [Hello ImGui](https://pthom.github.io/hello_imgui) is a library based on ImGui that enables to easily create applications with ImGui. It handles window creation, backend initialization (SDL, GLFW, etc.), cross-platform assets, docking layout, and more.
* [ImmApp](https://github.com/pthom/imgui_bundle/blob/main/external/immapp/immapp/runner.h) (aka "Immediate App", a submodule of ImGuiBundle) is a thin extension of Hello ImGui that enables to easily initialize the ImGuiBundle addons that require additional setup at startup.
## Hello World in 4 lines
4 lines are enough to start a GUI application!
Python:
```python
from imgui_bundle import imgui, immapp
def gui():
imgui.text("Hello, world!")
immapp.run(gui)
```
C++:
```cpp
#include "immapp/immapp.h"
#include "imgui.h"
void gui() { ImGui::Text("Hello, world!"); }
int main() { ImmApp::Run(gui); }
```
## A more complete example with plots
The example below shows how to create a more complete application that uses an add-on (ImPlot) for plotting data.
Python:
```python
import time
import numpy as np
from imgui_bundle import implot, imgui, immapp, imgui_knobs, hello_imgui
# Fill x and y whose plot is a heart
vals = np.arange(0, np.pi * 2, 0.01)
x = np.power(np.sin(vals), 3) * 16
y = 13 * np.cos(vals) - 5 * np.cos(2 * vals) - 2 * np.cos(3 * vals) - np.cos(4 * vals)
# Heart pulse rate and time tracking
phase = 0.0
t0 = time.time() + 0.2
heart_pulse_rate = 80
def gui():
global heart_pulse_rate, phase, t0, x, y
# Change heart size over time, according to the pulse rate
t = time.time()
phase += (t - t0) * heart_pulse_rate / (np.pi * 2)
k = 0.8 + 0.1 * np.cos(phase)
t0 = t
# Plot the heart
if implot.begin_plot("Heart", immapp.em_to_vec2(21, 21)):
implot.plot_line("", x * k, y * k)
implot.end_plot()
# The heart beats on its own: the app keeps its full speed while the plot is visible
hello_imgui.set_item_is_live()
# let the user set the pulse rate via a knob
_, heart_pulse_rate = imgui_knobs.knob("Pulse Rate", heart_pulse_rate, 30.0, 180.0)
if __name__ == "__main__":
immapp.run(gui, window_size_auto=True, window_title="Hello!", with_implot=True)
```
C++:
```cpp
#include "imgui.h"
#include "implot/implot.h"
#include "imgui-knobs/imgui-knobs.h"
#include "immapp/immapp.h"
#include "hello_imgui/hello_imgui.h"
#include
std::vector VectorTimesK(const std::vector& values, double k)
{
std::vector r(values.size(), 0.);
for (size_t i = 0; i < values.size(); ++i)
r[i] = k * values[i];
return r;
}
int main(int , char *[]) {
// Fill x and y whose plot is a heart
double pi = 3.1415926535;
std::vector x, y; {
for (double t = 0.; t < pi * 2.; t += 0.01) {
x.push_back(pow(sin(t), 3.) * 16.);
y.push_back(13. * cos(t) - 5 * cos(2. * t) - 2 * cos(3. * t) - cos(4. * t));
}
}
// Heart pulse rate and time tracking
double phase = 0., t0 = ImmApp::ClockSeconds() + 0.2;
float heart_pulse_rate = 80.;
auto gui = [&]() {
// Change heart size over time, according to the pulse rate
double t = ImmApp::ClockSeconds();
phase += (t - t0) * (double)heart_pulse_rate / (pi * 2.);
double k = 0.8 + 0.1 * cos(phase);
t0 = t;
auto xk = VectorTimesK(x, k), yk = VectorTimesK(y, k);
// Plot the heart
if (ImPlot::BeginPlot("Heart", ImmApp::EmToVec2(21, 21)))
{
ImPlot::PlotLine("", xk.data(), yk.data(), (int)xk.size());
ImPlot::EndPlot();
// The heart beats on its own: the app keeps its full speed while the plot is visible
HelloImGui::SetItemIsLive();
}
// let the user set the pulse rate via a knob
ImGuiKnobs::Knob("Pulse", &heart_pulse_rate, 30., 180.);
};
ImmApp::AddOnsParams addOnsParams{.withImplot = true};
HelloImGui::SimpleRunnerParams runnerParams {
.guiFunction = gui,
.windowTitle = "Hello!",
.windowSizeAuto = true,
};
ImmApp::Run(runnerParams, addOnsParams);
}
```
# Quickly deploy your apps on the web
These apps can be easily deployed on the web, either in C++ via Emscripten, or in Python via Pyodide.
* Online demo (C++/Emscripten): [Heart Pulse Demo](https://imgui-bundle.pages.dev/explorer/haiku_implot_heart.html)
* Online demo (Python/Pyodide): [Heart Pulse Demo - Pyodide](https://imgui-bundle.pages.dev/min_pyodide_app/demo_heart), and [html + python source code](https://imgui-bundle.pages.dev/min_pyodide_app/demo_heart.source.txt)
--------------------------------------------------------------------------------
Page: https://imgui-bundle.pages.dev/doc/intro/compare/
# How Does It Compare?
Not sure if Dear ImGui Bundle is right for you? Compare the code styles with other popular GUI libraries, when creating the app below:
ImGui Bundle:
**12 lines** – True immediate mode: UI declaration *is* the event handler
```python
from imgui_bundle import imgui, hello_imgui
selected_idx = 0
items = ["Apple", "Banana", "Cherry"]
def gui():
global selected_idx
imgui.text("Choose a fruit:")
_changed, selected_idx = imgui.list_box("##fruits", selected_idx, items)
imgui.text(f"You selected: {items[selected_idx]}")
hello_imgui.run(gui, window_title="Fruit Picker", window_size_auto=True)
```
**Strengths**: Simplest code, real-time capable, runs on desktop + web (Pyodide), 20+ integrated libraries, full C++ support
**Best for**: Tools, visualization, games, scientific apps
Qt:
**31 lines** – Retained mode with class hierarchy and signals/slots
```python
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QListWidget
items = ["Apple", "Banana", "Cherry"]
class FruitPicker(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout()
self.label = QLabel("Choose a fruit:")
self.list_widget = QListWidget()
self.list_widget.addItems(items)
self.result_label = QLabel(f"You selected: {items[0]}")
self.list_widget.currentRowChanged.connect(self.on_selection_changed)
layout.addWidget(self.label)
layout.addWidget(self.list_widget)
layout.addWidget(self.result_label)
self.setLayout(layout)
def on_selection_changed(self, index):
self.result_label.setText(f"You selected: {items[index]}")
app = QApplication([])
window = FruitPicker()
window.show()
app.exec()
```
**Qt strengths**: More widgets, Qt Designer, larger ecosystem, rich text, accessibility, native look
**ImGui Bundle strengths**: Simpler code, real-time, lighter weight, scientific viz, easier cross-compilation
**Qt is Best for**: Traditional business apps, enterprise software
DearPyGui:
**29 lines** – ImGui-based but with retained-mode API and callbacks
```python
import dearpygui.dearpygui as dpg
items = ["Apple", "Banana", "Cherry"]
dpg.create_context()
def on_selection_changed(sender, app_data):
dpg.set_value("result_label", f"You selected: {app_data}")
with dpg.window(tag="Primary Window", label="Fruit Picker"):
dpg.add_text("Choose a fruit:")
dpg.add_listbox(items=items, callback=on_selection_changed, num_items=len(items))
dpg.add_text("You selected: ", tag="result_label")
dpg.create_viewport(title='Fruit Picker', width=400, height=300)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.set_primary_window("Primary Window", True)
dpg.start_dearpygui()
dpg.destroy_context()
```
**DearPyGui strengths**: Familiar retained-mode API, large user base, good reputation
**ImGui Bundle strengths**: True immediate mode, more libraries (~20), C++ support, Pyodide web support
**DearPyGui is Best for**: Developers who prefer retained-mode patterns
NiceGUI:
**15 lines** – Web-based with callbacks
```python
from nicegui import ui
selected_idx = -1
items = ["Apple", "Banana", "Cherry"]
def on_selection_change(e):
global selected_idx
selected_idx = items.index(e.value)
selection_label.text = f"You selected: {e.value}"
ui.label("Choose a fruit:")
dropdown = ui.select(options=items, value=items[0], on_change=on_selection_change)
selection_label = ui.label(f"You selected: {items[0]}")
ui.run(title="Fruit Picker")
```
**NiceGUI strengths**: Web-native, modern UI, easy deployment, familiar web paradigm, reactive
**ImGui Bundle strengths**: Native performance, desktop-native, offline capable, advanced widgets, lower latency
**NiceGUI is Best for**: Web-first apps, internal dashboards, CRUD interfaces
Gradio:
**18 lines** – Declarative blocks with event wiring
```python
import gradio as gr
items = ["Apple", "Banana", "Cherry"]
selected_item = items[0]
def on_selection_change(choice):
global selected_item
selected_item = choice
return f"You selected: {choice}"
with gr.Blocks() as demo:
gr.Markdown("# Fruit Picker")
gr.Markdown("Choose a fruit:")
dropdown = gr.Dropdown(choices=items, value=items[0], label="Choose a fruit")
output = gr.Textbox(value=f"You selected: {items[0]}", label="Selection", interactive=False)
dropdown.change(fn=on_selection_change, inputs=dropdown, outputs=output)
demo.launch()
```
**Gradio strengths**: Web-native, ML-focused, Hugging Face integration, easy sharing, pre-built media components
**ImGui Bundle strengths**: Native performance, desktop-native, stateful apps, professional tools, flexibility
**Gradio is Best for**: ML model demos, Hugging Face Spaces, sharing with non-technical users
Note:
These examples are [available here](https://github.com/pthom/imgui_bundle/tree/main/bindings/imgui_bundle/demos_python/sandbox/compare_other_libs)
--------------------------------------------------------------------------------
Page: https://imgui-bundle.pages.dev/doc/intro/interactive-manuals/
# Interactive Manuals
## Dear ImGui Explorer
[Dear ImGui Explorer](https://pthom.github.io/imgui_explorer/) lets you explore all the widgets and features of Dear ImGui, with live examples and the corresponding python or C++ code. It is built using Dear ImGui Bundle.
Its "API" tab documents the code: click a name in the code, then the book button, and you get its Python and C++ signatures, its doc, where the demo uses it, and links to the [API reference](https://imgui-bundle.pages.dev/doc/api/). A tooltip gives the same for the identifier under the mouse.
## Dear ImGui Bundle Explorer
[Dear ImGui Bundle Explorer](https://imgui-bundle.pages.dev/explorer/): interactive reference manual - browse demos, see the code, try the widgets.
It opens on a welcome page, with a carousel of what the bundle can do. Its "Demos" page is the catalog of demos, by category: starter apps, tours of the libraries, interactive manuals, each with its Python and C++ code.
## Online Python Playground
[Online Python Playground](https://imgui-bundle.pages.dev/playground/): an online Python sandbox with ready-to-run demos - edit code, see results instantly.
--------------------------------------------------------------------------------
Page: https://imgui-bundle.pages.dev/doc/intro/examples-gallery/
# Made with Dear ImGui Bundle
Applications built with Dear ImGui Bundle. More in the [Gallery](https://github.com/pthom/imgui_bundle/discussions/107): add yours!
The bundle's own demos are in [Demos & Tutorials](https://imgui-bundle.pages.dev/doc/intro/demos/).
## 4K4D
A research project aimed for CVPR 2024, using python bindings (ImGui Bundle).
```
@inproceedings{xu20244k4d,
title={4K4D: Real-Time 4D View Synthesis at 4K Resolution},
author={Xu, Zhen and Peng, Sida and Lin, Haotong and He, Guangzhao and Sun, Jiaming and Shen, Yujun and Bao, Hujun and Zhou, Xiaowei},
booktitle={CVPR},
year={2024}
}
```
[ 4K4D: Real-Time 4D View Synthesis at 4K Resolution](https://zju3dv.github.io/4k4d/)
A volumetric video, showing an ImGui interface to control the rendering parameters.
## HDRview
[HDRview](https://github.com/wkjarosz/hdrview) is a research-oriented image viewer with an emphasis on examining and comparing high-dynamic range (HDR) images.
It is developed by Wojciech Jarosz and is built using Hello ImGui (which is included in Dear ImGui Bundle), in C++.
It runs on Windows, Linux, macOS, iOS, and on the web via emscripten!
An HDR photograph open in HDRview, alongside several multi-view and multi-part EXRs, with the Log window open below the viewport.
Access HDRview online: [https://wkjarosz.github.io/hdrview/](
https://wkjarosz.github.io/hdrview/)
--------------------------------------------------------------------------------
Page: https://imgui-bundle.pages.dev/doc/intro/resources/
# Resources
## Start here
- [Home page](https://imgui-bundle.pages.dev/): the project's site
- [Interactive Explorer](https://imgui-bundle.pages.dev/explorer/): all the libraries, with live demos and their C++ and Python code
- [Python Playground](https://imgui-bundle.pages.dev/playground/): a live Python sandbox with ready-to-run demos: edit the code, see the result at once
- [Documentation](https://imgui-bundle.pages.dev/doc/): the full documentation, with the [API reference](https://imgui-bundle.pages.dev/doc/api/) of every library
- [GitHub](https://github.com/pthom/imgui_bundle): the source code, issues and discussions
- [Discord](https://discord.gg/xkzpKMeYN3): the community, for questions, showcase and discussion
- [DeepWiki](https://deepwiki.com/pthom/imgui_bundle): AI-powered Q&A about the framework
## Documentation
- [Dear ImGui Bundle documentation](https://imgui-bundle.pages.dev/doc/), also as a [PDF](https://imgui-bundle.pages.dev/doc/assets/imgui_bundle_book.pdf)
- [API reference](https://imgui-bundle.pages.dev/doc/api/): every function, class and enum of each library, with its Python and C++ signatures; also [in plain text](https://imgui-bundle.pages.dev/llms/api/index.txt), for AI assistants
- [For AI assistants](https://imgui-bundle.pages.dev/doc/intro/ai-guide/): a page written for them (also at https://imgui-bundle.pages.dev/llms.txt), and the book [in plain text](https://imgui-bundle.pages.dev/llms-full.txt)
- [Hello ImGui documentation](https://pthom.github.io/hello_imgui), also as a [PDF](https://pthom.github.io/hello_imgui/hello_imgui_book.pdf). Hello ImGui provides a simple framework to quickly create applications using Dear ImGui. It is included in Dear ImGui Bundle.
- [Fiatlight documentation](https://pthom.github.io/fiatlight), also as a [PDF](https://pthom.github.io/fiatlight/flgt.pdf). Fiatlight provides automatic UI generation for functions and structured data (dataclasses, pydantic models), making it a powerful tool for rapid prototyping and application development. It is built on top of Dear ImGui Bundle.
- [litgen documentation](https://pthom.github.io/litgen/): the generator of the Python bindings
You may also upload the PDF manuals to a chat with an AI assistant, so that it can help you when using the libraries.
[Ask DeepWiki](https://deepwiki.com/pthom/imgui_bundle): DeepWiki makes it easy to search and ask questions about Dear ImGui Bundle and its integrated libraries. It is generated by AI, based on the full source code and documentation. Quite useful, even if some inconsistencies may occur.
(for [Dear ImGui](https://deepwiki.com/ocornut/imgui) - [Dear ImGui Bundle](https://deepwiki.com/pthom/imgui_bundle) - [Hello ImGui](https://deepwiki.com/pthom/hello_imgui))
## Interactive manuals
The manuals and demos below are using Dear ImGui Bundle itself!
- [Dear ImGui Bundle Explorer](https://imgui-bundle.pages.dev/explorer/): interactive reference manual - browse demos, see the code, try the widgets
- [Online Python Playground](https://imgui-bundle.pages.dev/playground/): live Python sandbox with ready-to-run demos - edit code, see results instantly
- [Dear ImGui Explorer](https://pthom.github.io/imgui_explorer/): interactive manual for Dear ImGui, ImPlot, ImPlot3D
## Community
- [Discord](https://discord.gg/xkzpKMeYN3): join the community for questions, showcase, and discussion
- [GitHub Discussions](https://github.com/pthom/imgui_bundle/discussions): searchable Q&A
- [FAQ](https://github.com/pthom/imgui_bundle/issues?q=is%3Aissue+label%3AFAQ): answers to common questions, as issues
## Repositories
- [Dear ImGui official repository](https://github.com/ocornut/imgui)
- [Dear ImGui Bundle repository](https://github.com/pthom/imgui_bundle)
- [Hello ImGui repository](https://github.com/pthom/hello_imgui)
- [Litgen (bindings generator) repository](https://github.com/pthom/litgen)
- [Fiatlight repository](https://github.com/pthom/fiatlight)
## Videos
A series of video tutorials about Dear ImGui Bundle, Hello ImGui and Fiatlight:
- [Dear ImGui Bundle - YouTube Playlist](https://www.youtube.com/playlist?list=PLaJx_KrDECZPzttQ77Gv8DD7OAUwmtWUc)
--------------------------------------------------------------------------------
Page: https://imgui-bundle.pages.dev/doc/python/python-imgui-intro/
# Introduction
# Immediate GUI in Python with Dear ImGui Bundle
The most popular Immediate Mode GUI library is [Dear ImGui](https://github.com/ocornut/imgui), a powerful **C++** library originally created for real-time tools in game engines, now widely used in many industries, with over 60k stars on GitHub.
For Python, [Dear ImGui Bundle](https://github.com/pthom/imgui_bundle) brings full Dear ImGui support plus many extra libraries, making it ideal for rapid prototyping as well as building complex apps with advanced widgets, plotting, node editors, and more.
The python bindings are heavily documented so that they are easy to browse. They are also autogenerated, so that they are always up-to-date.
# Anatomy of an application with Dear ImGui Bundle
`imgui_bundle` is a Python package that unifies multiple Dear ImGui-related submodules:
* `imgui`: the core Dear ImGui library
* `implot` and `implot3d`: for advanced, real-time plotting
* `rich_md`: markdown rendering for imgui
* `hello_imgui`: an approachable starter kit for new apps
* `immapp`: helper to activate "addons" (like implot, markdown, etc.)
* Plus about 20 other powerful tools
The example below is heavily commented and shows how to create a simple app that combines Markdown text and an animated plot using `implot`:
```python
import numpy as np
from imgui_bundle import imgui, implot, rich_md, hello_imgui, immapp
def gui():
# Render Markdown text
rich_md.render("""
# Render an animated plot with ImPlot
This example uses `ImPlot` for real-time plotting, and `rich_md` for markdown.
""")
# Render an animated plot (updates every frame)
if implot.begin_plot(
title_id="Plot",
# size in em units (1em = height of a character)
size=hello_imgui.em_to_vec2(40, 20)):
x = np.arange(0, np.pi * 4, 0.01)
y = np.cos(x + imgui.get_time())
implot.plot_line("y1", x, y)
implot.end_plot()
if imgui.button("Exit"):
hello_imgui.get_runner_params().app_shall_exit = True
# Run the app with ImPlot and markdown support
immapp.run(gui,
with_implot=True,
with_markdown=True,
window_size=(700, 500))
```
# Deploy your applications
Dear ImGui Bundle apps are highly portable—they can run as standalone Python scripts, in Jupyter notebooks, or even directly in web browsers via Pyodide.
* **Standalone scripts:** Run on any PC (Windows, macOS, Linux) with minimal setup.
* **Jupyter notebooks:** The app runs in a separate window, and a screenshot is displayed in the notebook after closing (requires running Jupyter locally).
* **Web (Pyodide):** No server or installation required—just a static HTML file. Your Python app runs in the browser, with the package downloaded from a CDN.
--------------------------------------------------------------------------------
Page: https://imgui-bundle.pages.dev/doc/python/python-install/
# Install for Python
## Install from pypi
```bash
# Minimal install
pip install imgui-bundle
# or to get all optional features:
pip install "imgui-bundle[full]"
```
Binary wheels are available for Windows, macOS and Linux. If a compilation from source is needed, the build process might take up to 5 minutes, and will require an internet connection.
*Platform notes*
* _Windows_: Under windows, you might need to install the [msvc redist](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#visual-studio-2015-2017-2019-and-2022)
* _macOS_ : under macOS, if a binary wheel is not available (e.g. for older macOS versions), pip will try to compile from source. This might fail if you do not have XCode installed. In this case, install imgui-bundle with the following command `SYSTEM_VERSION_COMPAT=0 pip install --only-binary=:all: imgui_bundle`
## Install from source
```bash
# Clone the repository
git clone https://github.com/pthom/imgui_bundle.git
cd imgui_bundle
# Build and install the package (minimal install)
pip install -v .
# or build and install the package with all optional features:
# pip install -v ".[full]"
```
The build process might take up to 5 minutes, and will clone the submodules if needed (an internet connection is required).
## Run the python demo
The demo needs the optional features: after a minimal install, it stops at start ("Dear ImGui Bundle Explorer requires numpy!").
```bash
pip install "imgui-bundle[full]"
imgui_bundle_demo
```
The source for the demos can be found inside [bindings/imgui_bundle/demos_python](https://github.com/pthom/imgui_bundle/tree/main/bindings/imgui_bundle/demos_python).
TIP: Consider `imgui_bundle_demo` as an always available manual for Dear ImGui Bundle with lots of examples and related code source.
## Next Steps
- **[Dear ImGui Basics](https://imgui-bundle.pages.dev/doc/core-libs/imgui/)** – Learn ImGui concepts (widgets, IDs, patterns)
- **[Hello ImGui & ImmApp](https://imgui-bundle.pages.dev/doc/core-libs/hello-imgui-immapp/)** – App runners, configuration, DPI handling
- **[Python Tips](https://imgui-bundle.pages.dev/doc/python/python-tips/)** – Context managers, C++ to Python translation, debugging
- **[Assets](https://imgui-bundle.pages.dev/doc/python/python-assets/)** – Managing fonts, images, and resources
--------------------------------------------------------------------------------
Page: https://imgui-bundle.pages.dev/doc/python/python-assets/
# Assets folder
(for python)
hello_imgui and immapp applications rely on the presence of an `assets/` folder.
**This folder stores:**
* Default fonts used by the markdown renderer (if the markdown addon is used).
* All the resources (images, fonts, etc.) used by the application. Feel free to add any resources there!
**Assets folder location**
Place the assets folder in the same folder as the script.
**If needed, change the assets folder location:**
Call `hello_imgui.set_assets_folder()` at startup.
**Typical layout of the assets folder**
```
assets/
+-- fonts/
| +-- DroidSans.ttf # Default fonts used by HelloImGui to
| +-- fontawesome-webfont.ttf # improve text rendering (esp. on High DPI)
| | # if absent, a default LowRes font is used.
| |
| +-- Roboto/ # Optional: fonts for markdown
| +-- LICENSE.txt
| +-- Roboto-Bold.ttf
| +-- Roboto-BoldItalic.ttf
| +-- Roboto-Regular.ttf
| +-- Roboto-RegularItalic.ttf
| +-- Inconsolata-Medium.ttf
+-- images/
+-- markdown_broken_image.png # Optional: used for markdown
+-- world.png # Add anything in the assets folder!
```
Note: in C++, the assets folder also contains an `app_settings` folder, which contains application settings and app icons for different platforms. This is not needed / not available in Python applications.
**Where to find the default assets**
You can [download the default assets as a zip file](https://imgui-bundle.pages.dev/resources/assets.zip).
Look at the folder [imgui_bundle/bindings/imgui_bundle/assets](https://github.com/pthom/imgui_bundle/tree/main/bindings/imgui_bundle/assets) to see its content.
## Fonts and images
Fonts are loaded in the `load_additional_fonts` callback, with paths relative to the assets folder:
```python
from imgui_bundle import hello_imgui
def load_fonts():
# Load a font at 18px size
hello_imgui.load_font("fonts/Roboto-Regular.ttf", 18.0)
# Load with options (e.g., merge icons into previous font)
font_params = hello_imgui.FontLoadingParams()
font_params.merge_to_last_font = True
hello_imgui.load_font("fonts/icons.ttf", 16.0, font_params)
params = hello_imgui.RunnerParams()
params.callbacks.load_additional_fonts = load_fonts
```
Images are displayed from their path in the assets folder:
```python
from imgui_bundle import hello_imgui, imgui
def gui():
# Load and display an image from assets
hello_imgui.image_from_asset("images/logo.png", imgui.ImVec2(100, 100))
# Or with its texture, e.g. for imgui.image() (which takes an ImTextureRef)
texture = hello_imgui.im_texture_id_from_asset("images/logo.png")
imgui.image(imgui.ImTextureRef(texture), imgui.ImVec2(100, 100))
```
## Troubleshooting
**"Assets not found" or missing fonts/images:**
1. Ensure the `assets/` folder is in the same directory as your script
2. If running from a different directory, set the path explicitly:
```python
from imgui_bundle import hello_imgui
hello_imgui.set_assets_folder("/path/to/your/assets")
```
3. For packaged applications, ensure assets are included in your distribution
--------------------------------------------------------------------------------
Page: https://imgui-bundle.pages.dev/doc/python/pure-python-backend/
# Pure Python Backends
Pure Python backends in ImGui Bundle let you use ImGui with Python-only windowing and rendering libraries instead of the default C++ GLFW+OpenGL backend. This gives you full control over the application loop but requires manual setup of windowing, input handling, and rendering.
**Key Differences**
* No Hello ImGui features: Pure Python backends don't provide DPI handling, themes, asset management, or other Hello ImGui conveniences
* Manual setup required: You must handle window creation, input events, and the render loop yourself
* Texture handling: Backends must implement support for dynamic fonts (ImGui 1.92+)
[python_backends](https://github.com/pthom/imgui_bundle/tree/main/bindings/imgui_bundle/python_backends) contains pure python backends for glfw, pyglet, pygame, sdl2 and sdl3. They do not offer the same DPI handling as HelloImGui, but they are a good starting point if you want to use alternative backends.
See [examples](https://github.com/pthom/imgui_bundle/tree/main/bindings/imgui_bundle/python_backends/examples) where you will find:
* example_python_backend_glfw3.py
* example_python_backend_pygame.py
* example_python_backend_pyglet.py
* example_python_backend_sdl2.py
* example_python_backend_sdl3.py
* example_python_backend_wgpu.py
Note:
Some other python libraries also provide ImGui integration, using Dear ImGui Bundle.
See for example:
* [wgpu-py](https://github.com/pygfx/wgpu-py/blob/main/examples/imgui_basic_example.py)
* [moderngl-window](https://github.com/moderngl/moderngl-window/blob/master/examples/integration_imgui.py)
--------------------------------------------------------------------------------
Page: https://imgui-bundle.pages.dev/doc/python/python-async/
# Async Support
_(Since v1.92.6)_
ImGui Bundle provides async/await support that enables **true parallel execution** of Python code alongside GUI rendering. This allows your Python computations to run at full speed while the GUI remains responsive.
_Note: an async execution mode is also available for Jupyter notebooks; see [Notebook Usage](https://imgui-bundle.pages.dev/doc/python/notebook-runners/) for details._
## Overview
`immapp.run_async()` and `hello_imgui.run_async()` function allows you to run ImGui applications asynchronously using Python's `asyncio` framework. This is particularly useful when:
- You need to perform computations while the GUI is running
- You're building data visualization dashboards with live updates
- You want to integrate ImGui into async Python applications
- You're working in Jupyter notebooks (see [Notebook Usage](https://imgui-bundle.pages.dev/doc/python/notebook-runners/))
## Quick Example
Here's a simple example showing parallel execution:
```python
import asyncio
import time
from imgui_bundle import immapp, imgui, hello_imgui
GUI_FINISHED = False
COMPUTATION_COUNT = 0
START_TIME = time.time()
def gui():
params = hello_imgui.get_runner_params()
idling_params = params.fps_idling
idling_params.fps_idling_mode = hello_imgui.FpsIdlingMode.early_return
idling_params.vsync_to_monitor = False
idling_params.fps_max = 60.0
imgui.text(f"GUI FPS: {hello_imgui.frame_rate():.1f}")
imgui.text(f"Computations per second: {COMPUTATION_COUNT / (time.time() - START_TIME):.1f}")
global GUI_FINISHED
GUI_FINISHED = hello_imgui.get_runner_params().app_shall_exit
async def python_computation_loop():
"""Run computations while GUI is active."""
"""Python code which runs in parallel with the GUI!"""
global COMPUTATION_COUNT
while not GUI_FINISHED:
_ = sum(range(1000)) # Do some work
COMPUTATION_COUNT += 1
await asyncio.sleep(0) # Yield to event loop (required for async cooperation)
async def main():
# Start GUI as an asyncio task (non-blocking)
_gui_task = asyncio.create_task(immapp.run_async(gui, window_size_auto=True))
# Run computations in parallel
await python_computation_loop()
if __name__ == "__main__":
asyncio.run(main())
```
Also see
[`demos_python_specifics/demo_run_async.py`](https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_python/demos_python_specifics/demo_run_async.py)
## Automatic FPS Optimization
`immapp.run_async` automatically adjusts FPS idling parameters to optimize performance, so that the Python loop
can run at maximum speed.
The settings below are applied automatically by `immapp.run_async` to ensure that the GUI rendering
returns early to Python instead of sleeping, allowing maximum parallelism between GUI rendering and Python code execution:
```python
runner_params.fps_idling.fps_idling_mode = hello_imgui.FpsIdlingMode.early_return
runner_params.fps_idling.vsync_to_monitor = False
runner_params.fps_idling.fps_max = 60.0
```
## Signature Patterns
`run_async()` supports two different ways to configure your application:
### 1. Simple GUI Function
```python
async def gui():
imgui.text("Hello, World!")
if imgui.button("Click me"):
print("Button clicked!")
await immapp.run_async(
gui,
window_title="My App",
window_size_auto=True,
top_most=True,
# Optional addons (immapp only)
with_implot=True,
with_markdown=True
)
```
### 2. Full RunnerParams (Maximum Control)
```python
from imgui_bundle import hello_imgui, immapp
runner_params = hello_imgui.RunnerParams()
runner_params.callbacks.show_gui = gui
runner_params.app_window_params.window_title = "My App"
runner_params.imgui_window_params.show_menu_bar = True
# With immapp, you can use AddOnsParams
addons = immapp.AddOnsParams()
addons.with_implot = True
addons.with_node_editor = True
asyncio.run(immapp.run_async(runner_params, addons))
```
## Yielding to the Event Loop
In your async code, you **must** regularly yield control to the event loop to allow the GUI to render:
```python
async def my_computation():
while condition:
# Do some work
result = expensive_computation()
# Yield to allow GUI rendering (critical!)
await asyncio.sleep(0)
```
Without `await asyncio.sleep(0)`, the GUI will freeze because asyncio can't switch between tasks.
## In the browser
The same code runs in the browser, with [Pyodide](https://pyodide.org), whose event loop is the browser's:
- Start the app with `asyncio.ensure_future(main())`: `asyncio.run()` fails there, an event loop runs already.
- Yield with a short sleep (e.g. `await asyncio.sleep(0.02)`), after a slice of work: the browser draws the page only while Python sleeps, and `await asyncio.sleep(0)` would freeze it.
The demo `demo_run_async.py` does both (it runs in the [playground](https://imgui-bundle.pages.dev/playground/?demo=demo_run_async.py)).
## Downloads that do not block the GUI
`immapp.start_download()` starts an HTTP request in the background, from a GUI function. It works with `immapp.run` and `immapp.run_async`, on the desktop (in a thread) and in the browser (with a fetch). Look at the result's `done` at each frame:
```python
from imgui_bundle import imgui, immapp
download: immapp.Download | None = None
data, error = b"", ""
def gui() -> None:
global download, data, error
if imgui.button("Download"):
download = immapp.start_download("https://example.com/data.json")
if download is not None and download.done:
data, error = download.data, download.error
download = None
if download is not None:
imgui.text("Downloading...")
elif error:
imgui.text(error)
immapp.run(gui)
```
- `error` is empty on success. Otherwise it gives the HTTP status and the start of the body, where web APIs explain their errors (`HTTP 429 Too Many Requests: ...`), or the network failure.
- `status` gives the HTTP status, and `data` the body, also with an error status.
- `method="POST"` with `json_body=...` sends JSON. `timeout_s` (30 s by default) limits the wait for the answer.
- `headers={...}` adds HTTP headers, e.g. an API key: `{"Authorization": "Bearer "}`.
- `immapp.download_url_bytes()` waits until the data is there: fine in a script, but it freezes a GUI meanwhile.
## Troubleshooting
### GUI Freezes
**Problem**: The GUI becomes unresponsive during computations.
**Solution**: Make sure to `await asyncio.sleep(0)` regularly in your computation loops.
### Exceptions in the async GUI
If your GUI raises an exception, it might be difficult to trace with the GUI is running in an async way.
In that case, it is recommended to first test your GUI in blocking mode using `immapp.run`, which will propagate exceptions normally.
Once your GUI works in blocking mode, you can then switch to non-blocking mode (`immapp.run_async`).
--------------------------------------------------------------------------------
Page: https://imgui-bundle.pages.dev/doc/python/notebook-runners/
# Jupyter Notebook support
# Introduction
The notebook submodules (`immapp.nb` and `hello_imgui.nb`) provide convenient functions for the usage in a local jupyter notebook, with two main modes:
* **blocking mode**: other cells cannot be run in parallel. A screenshot is displayed after the application exits.
* **non-blocking mode**: other cells can be run in parallel. The application window updates live.
Note:
_Note: Working on a remote notebook (or via Google Collab) may not work, since it requires a local X11 server (it might work if using X11 formwarding)._
# Blocking mode
## API
`immapp.nb.run` and `hello_imgui.nb.run` functions will run a GUI application, wait for it to exit, and display a screenshot of the final application screen in the cell output.
_During the application execution, other cells cannot be run._
**Parameters**
`immapp.nb.run` and `hello_imgui.nb.run` accept the same parameters as `immapp.run` and `hello_imgui.run`, respectively.
Optional additional parameters to controls the screenshot size (choose only one of the two):
* thumbnail_ratio: (default=1.0)
You can use it to change the size of the thumbnail.
Passing 0.5 will create a thumbnail half the width of the window.
* thumbnail_height: (default=0)
You can use it to set a fixed height for the thumbnail (in pixels).
If 0, the height is computed from the app window size.
## Example
The example cell below demonstrates the blocking mode using `immapp.nb.run`. It shows a sinusoidal curve that can be adjusted with a slider. After closing the application window, a screenshot of the final state is displayed in the cell output.
```python
from imgui_bundle import implot, immapp, imgui
import numpy as np
FREQ = 0.1
def gui():
global FREQ
_, FREQ = imgui.slider_float("Frequency", FREQ, 0.01, 1.0)
x = np.arange(0, 100, 0.1)
y = np.sin(FREQ * x)
if implot.begin_plot("My plot"):
implot.plot_line("Sine wave", y)
implot.end_plot()
immapp.nb.run(gui, window_size=(600, 350), with_implot=True, thumbnail_height=500)
```
# Non blocking mode
_(Since v1.92.6)_
## API
### start
* `immapp.nb.start` and `hello_imgui.nb.start` will run a GUI application, display it in a top-most window on top of the browser.
**Other cells can be run while the application is running. The application window will update live.**
_Note: these function return an `asyncio.Task`, which may be awaited or managed using asyncio._
**Parameters**
`immapp.nb.start` and `hello_imgui.nb.start` accept the same parameters as `immapp.start` and `hello_imgui.start`, respectively.
Optional additional parameter: `top_most` to control if the application window should stay on top of other windows.
### is_running
* `immapp.nb.is_running` and `hello_imgui.nb.is_running` return True if the application is running, False otherwise.
### stop
* `immapp.nb.stop` and `hello_imgui.nb.stop` will stop the running application.
Tip:
Only one application can be run at a time from a notebook. Trying to start a new application while another one is running will exit the previous one.
_Note: If other cells are running while the application is running, they should call `await asyncio.sleep(0)` periodically to allow the application to update._
Important:
If your GUI raises an exception, it might be difficult to trace with the GUI is running in an async way.
In that case, it is recommended to first test your GUI in blocking mode using `immapp.nb.run`, which will propagate exceptions normally.
Once your GUI works in blocking mode, you can then switch to non-blocking mode (`immapp.nb.start`).
## Example
### Start the application
The cell below demonstrates the non-blocking mode using `immapp.nb.start`. It runs the same application as before (a sinusoidal curve that can be adjusted with a slider). You can modify the frequency while the application is running by changing the value of the `FREQ` variable in another cell.
When you run it, the cell exits immediately, but the GUI application continues to show and to be interactive (you can then run other cells while the application is running).
_Note: since, `immapp.nb.start` returns an `asyncio.Task`, you can see that the cell output shows the task information (Task pending, ...)._
Important:
In a non-blocking mode, the GUI will not be shown inside the notebook (not even as a screenshot). Instead, it will be displayed in a separate top-most window on top of the browser.
Refer to the "video demonstration" below for a demo of how the cells below will render on your screen.
```python
immapp.nb.start(gui, window_size=(500, 300), with_implot=True, top_most=True)
```
### Interact while the application is running
The cell below shows that it is possible to modify the frequency via code while the application is running, and the curve updates live.
```python
FREQ = 0.5 # Modify frequency while the app is running
```
### Check if the application is running
The cells below can be used to check if the application is running
```python
immapp.nb.is_running()
```
### Stop the application
```python
immapp.nb.stop()
```
### Video demonstration
Demonstration of the non-blocking mode in a Jupyter notebook.
# Example: Real-Time Data Stream Simulation
This example simulates a **live data stream** that continuously updates, like you might see in a monitoring dashboard or during ML training.
Tip:
Refer to the "video demonstration" below for a demo of how the cells below will render on your screen.
## Start the GUI
The cell below instantiate the application data (stream_data) and starts a GUI application that displays the live data stream.
```python
from imgui_bundle import immapp, imgui, hello_imgui, implot
import numpy as np
import time
# Streaming data buffer
stream_data = {
"values": [],
"max_points": 500,
"paused": False
}
def streaming_gui():
"""GUI that shows a live streaming plot"""
imgui.text("Live Data Stream")
imgui.text(f"Points: {len(stream_data['values'])}")
# Control buttons
if imgui.button("Pause" if not stream_data["paused"] else "Resume"):
stream_data["paused"] = not stream_data["paused"]
imgui.same_line()
if imgui.button("Clear"):
stream_data["values"].clear()
imgui.separator()
# Plot the streaming data
if len(stream_data["values"]) > 0:
if implot.begin_plot("Data Stream", hello_imgui.em_to_vec2(40, 15)):
x_data = np.arange(len(stream_data["values"]), dtype=np.float32)
y_data = np.array(stream_data["values"], dtype=np.float32)
implot.setup_axes("x", "y", implot.AxisFlags_.auto_fit, implot.AxisFlags_.auto_fit)
implot.plot_line("Value", x_data, y_data)
implot.end_plot()
if imgui.button("Close"):
hello_imgui.get_runner_params().app_shall_exit = True
# Start streaming GUI (note: immapp.nb.start is non-blocking
# and immediately returns an asyncio task)
immapp.nb.start(
streaming_gui,
window_title="Data Stream Demo",
window_size=(800, 400),
with_implot=True,
top_most=True
)
print("✓ Streaming GUI started!")
print("✓ Run the next cell to start the data stream.")
```
## Simulate Data Stream
The cell below simulates a data stream: this will add data points while the GUI displays them in real-time.
* The GUI is already running above (in an asyncio task)
* So, we define another asyncio task to add data points (stream_data_loop below), and we run it in async way.
This cell will run for 5 seconds: while it runs, you should see the GUI updating live with new data points.
Important:
It is important to call periodically `await asyncio.sleep(...)` in the loop, to yield control to the event loop, so that the GUI can update.
You may sleep for 0 seconds if you want to yield control with the shortest possible delay.
(in the example below, we sleep for 0.001 seconds to simulate a 100 Hz data stream).
```python
#
import time
import random
import asyncio
async def stream_data_loop():
print("Starting data stream... (will run for 10 seconds)")
start_time = time.time()
while time.time() - start_time < 5 and immapp.nb.is_running():
if not stream_data["paused"]:
# Add new data point
new_value = np.sin(time.time()) + random.gauss(0, 0.1)
stream_data["values"].append(new_value)
# Keep buffer size limited
if len(stream_data["values"]) > stream_data["max_points"]:
stream_data["values"].pop(0)
await asyncio.sleep(0.01) # Yield control to the event loop
print(f"✓ Stream finished. Final count: {len(stream_data['values'])} points")
# Run the streaming loop
await stream_data_loop()
```
## Video demonstration
Demonstration of the real-time data stream simulation in a Jupyter notebook.
# Example: Real-Time AI Training and tuning
**Video demonstration on youtube**
https://www.youtube.com/embed/VqLz5F_bk60
Real-Time AI Training and tuning with Dear ImGui Bundle in Jupyter Notebooks
**Links to notebooks**
* [notebook_ml_training_async.ipynb](https://github.com/pthom/imgui_bundle/blob/main/docs/book/python/notebook_ml_training_async.ipynb)
* [notebook_ml_training_threaded.ipynb](https://github.com/pthom/imgui_bundle/blob/main/docs/book/python/notebook_ml_training_threaded.ipynb)
--------------------------------------------------------------------------------
Page: https://imgui-bundle.pages.dev/doc/python/python-terminal/
# Terminal Emulator Widget
`imgui_bundle.imgui_terminal` (Python only) embeds a terminal emulator in your ImGui application: a real shell rendered as an ImGui widget, with colors, scrollback, text selection, and job control.
A zsh shell running inside an ImGui child window.
**Install**
```bash
pip install "imgui-bundle[terminal]" # adds the pyte VT100 emulator
```
**Quick start**
```python
from imgui_bundle import hello_imgui, imgui_ctx, immapp
from imgui_bundle.imgui_terminal import TerminalView, LocalShellTransport
mono_font = None
view = TerminalView()
LocalShellTransport().start(view) # spawns $SHELL behind a pty (POSIX)
def load_fonts():
global mono_font
mono_font = hello_imgui.load_font("fonts/Inconsolata-Medium.ttf", 16.0)
def gui():
with imgui_ctx.push_font(mono_font, 0.0): # the widget uses the active font
view.render_in_child("terminal")
params = hello_imgui.RunnerParams()
params.callbacks.load_additional_fonts = load_fonts
params.callbacks.show_gui = gui
immapp.run(params)
```
Full demo: [demo_terminal_pyte.py](https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_python/demos_terminal/demo_terminal_pyte.py), also available in the Widgets tab of the demo explorer.
## Architecture: widget vs transport
The module separates the *widget* from the *byte source*:
```
keyboard -> ImGui -> transport -> shell/remote -> view.feed -> pyte -> ImGui draws it
```
* **`TerminalView`** owns a [pyte](https://github.com/selectel/pyte) VT100 screen, draws it, and translates keyboard/mouse input. It knows nothing about where bytes come from: push output in with `view.feed(bytes)`, receive keystrokes via the `view.on_input` callback. `feed()` may be called from any thread, and asks for the next frames (`hello_imgui.request_refresh()`): the app does not idle while output streams in.
* A **transport** produces and consumes those bytes. `LocalShellTransport` runs a local shell behind a pseudo-terminal (macOS / Linux). Any object with `start(view)` / `stop()` works (`TerminalTransport` protocol); `start()` takes ownership of `view.on_input` / `view.on_resize`.
### Remote shell (SSH, websocket, robot companion computer...)
The same widget drives a remote shell: wire the callbacks to your channel and feed incoming bytes.
```python
view = TerminalView()
view.on_input = lambda data: channel.send(data) # keystrokes -> remote
view.on_resize = lambda cols, rows: channel.resize(cols, rows)
# in a background reader: for chunk in channel: view.feed(chunk)
```
When your reader thread changes what the GUI shows (connected, closed, an error), it calls `hello_imgui.request_refresh()`, so that the app shows it at once, even while it idles.
Runnable remote demos (in `demos_python/demos_terminal/`):
* [demo_terminal_ssh.py](https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_python/demos_terminal/demo_terminal_ssh.py) — over an SSH channel (paramiko)
* [demo_terminal_websocket.py](https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_python/demos_terminal/demo_terminal_websocket.py) + [pty_bridge_server.py](https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_python/demos_terminal/pty_bridge_server.py) — over a websocket to a host-side shell bridge
This websocket path is also how a **Pyodide / browser** build would work: there is no local pty in the browser, but the widget itself is pure Python and drives a remote shell over a websocket.
## Features
* ANSI / 256-color / truecolor rendering; interactive programs work (`vim`, `htop`, `tmux`, shells with completion)
* Scrollback with a native ImGui scrollbar; follows live output until you scroll up, typing snaps back
* Full keyboard: F-keys, Ctrl combos incl. job control (Ctrl-C / Ctrl-Z), Alt as Meta, Shift-Tab, and modifier-encoded arrows/Home/End (Ctrl/Alt-Left/Right for word jumps)
* Text selection: drag, double-click a word, triple-click a line, or click + shift-click across scrollback; copy with Cmd-C/V (macOS) or Ctrl-Shift-C/V, paste with right-click
* ANSI colors plus bold and underline
* Colors themable via `TerminalTheme`; the program-set window title is available as `view.title`
## Limitations
pyte is a solid VT100 emulator, not a complete xterm. Known gaps: no alternate screen buffer (full-screen apps leave their frames in scrollback), no application cursor keys mode, no bracketed paste, no mouse reporting to programs, and double-width (CJK/emoji) glyphs may overlap. Glyphs missing from your font render as replacement boxes (ImGui does no OS font fallback); use a well-covered monospace font.
The local-shell transport is POSIX only; on Windows, adapt it with [pywinpty](https://github.com/andfoy/pywinpty) (ConPTY) or use a remote transport.
--------------------------------------------------------------------------------
Page: https://imgui-bundle.pages.dev/doc/python/python-pyodide/
# Deploy to the web - Pyodide
Dear ImGui Bundle applications can be effortlessly deployed to the web using Pyodide, enabling Python code to run directly in web browsers. This capability allows developers to share interactive GUI applications without requiring users to install any software.
> **Note:** Pyodide cannot use large native packages (like TensorFlow or PyTorch), and initial loading can be slow.
## Pyodide Minimal Template
With Pyodide, web deployment is as easy as copying the HTML template below. The Python code is unchanged from what you'd use for desktop.
* [HTML template source](https://imgui-bundle.pages.dev/min_pyodide_app/demo_heart.source.txt)
* [HTML template (run it)](https://imgui-bundle.pages.dev/min_pyodide_app/demo_heart)
Important:
The HTML file must be served through a local web server (e.g. `python -m http.server`).
Opening it directly via `file://` prevents package loading.
### How it works
The [template](https://imgui-bundle.pages.dev/min_pyodide_app/demo_heart.source.txt) is organised into four clearly marked parts.
**Part 1 — Load Pyodide from a CDN**
Pyodide is a Python interpreter compiled to WebAssembly; it runs directly in the browser.
```html
```
Check [pyodide latest releases](https://github.com/pyodide/pyodide/releases) and update the URL accordingly.
**Part 2 — Python application code**
The Python code is embedded in a `
```
Alternative: keep the Python in a separate file (e.g. `app.py`) and fetch it at runtime — see Part 4 below.
**Part 3 — Page DOM + styles**
A `