ImTui
An immediate mode TUI library based on the popular Dear ImGui. Ideal for debug interfaces and real-time monitoring tools.
GitHub Overview
ggerganov/imtui
ImTui: Immediate Mode Text-based User Interface C++ Library
Repository:https://github.com/ggerganov/imtui
Homepage:https://imtui.ggerganov.com
Stars3,332
Watchers46
Forks141
Created:December 8, 2019
Language:C++
License:MIT License
Topics
texttuiuiuser-interface
Star History
Data as of: 7/25/2025, 11:08 AM
ImTui
ImTui is an immediate mode TUI library that ports the popular Dear ImGui library to terminal environments. It maintains ImGui's simple and intuitive API while enabling terminal application development.
Features
Immediate Mode GUI
- Immediate Mode: Simple approach requiring no state management, drawing every frame
- ImGui Compatible: Familiar interface based on Dear ImGui's API
- Lightweight: Header-only library for easy integration
Rich Widgets
- Basic Widgets: Buttons, text input, sliders, checkboxes
- Layout: Rows, columns, windows, menu bars
- Data Display: Tables, lists, trees
- Plotting: Graph and chart display functionality
Installation
Via vcpkg
vcpkg install imtui
Manual CMake Build
git clone https://github.com/ggerganov/imtui
cd imtui
mkdir build && cd build
cmake ..
make -j4
Basic Usage
Hello World
#include "imtui/imtui.h"
#include "imtui/imtui-impl-ncurses.h"
int main() {
IMTUI_CHECKVERSION();
ImTui::CreateContext();
auto screen = ImTui_ImplNcurses_Init(true);
ImTui_ImplText_Init();
bool demo_open = true;
while (demo_open) {
ImTui_ImplNcurses_NewFrame();
ImTui_ImplText_NewFrame();
ImTui::NewFrame();
ImTui::SetNextWindowPos(ImVec2(4, 2), ImGuiCond_Once);
ImTui::SetNextWindowSize(ImVec2(50, 10), ImGuiCond_Once);
if (ImTui::Begin("Hello ImTui!")) {
ImTui::Text("Hello, Terminal UI!");
static float value = 0.5f;
ImTui::SliderFloat("Value", &value, 0.0f, 1.0f);
if (ImTui::Button("Exit")) {
demo_open = false;
}
}
ImTui::End();
ImTui::Render();
ImTui_ImplText_RenderDrawData(ImTui::GetDrawData(), screen);
ImTui_ImplNcurses_DrawScreen();
}
ImTui_ImplText_Shutdown();
ImTui_ImplNcurses_Shutdown();
ImTui::DestroyContext();
return 0;
}
System Monitor Tool
#include "imtui/imtui.h"
#include "imtui/imtui-impl-ncurses.h"
#include <vector>
#include <cmath>
#include <chrono>
class SystemMonitor {
private:
std::vector<float> cpu_history;
std::vector<float> memory_history;
std::chrono::steady_clock::time_point last_update;
public:
SystemMonitor() : last_update(std::chrono::steady_clock::now()) {
cpu_history.reserve(100);
memory_history.reserve(100);
}
void update() {
auto now = std::chrono::steady_clock::now();
if (std::chrono::duration_cast<std::chrono::milliseconds>(now - last_update).count() > 100) {
// Simulated CPU usage
float cpu_usage = 30.0f + 20.0f * sin(cpu_history.size() * 0.1f);
float memory_usage = 60.0f + 15.0f * cos(memory_history.size() * 0.05f);
if (cpu_history.size() >= 100) cpu_history.erase(cpu_history.begin());
if (memory_history.size() >= 100) memory_history.erase(memory_history.begin());
cpu_history.push_back(cpu_usage);
memory_history.push_back(memory_usage);
last_update = now;
}
}
void render() {
ImTui::SetNextWindowPos(ImVec2(2, 1), ImGuiCond_Once);
ImTui::SetNextWindowSize(ImVec2(76, 20), ImGuiCond_Once);
if (ImTui::Begin("System Monitor")) {
// CPU usage
if (!cpu_history.empty()) {
ImTui::Text("CPU Usage: %.1f%%", cpu_history.back());
ImTui::PlotLines("##cpu", cpu_history.data(), cpu_history.size(),
0, nullptr, 0.0f, 100.0f, ImVec2(0, 40));
}
ImTui::Separator();
// Memory usage
if (!memory_history.empty()) {
ImTui::Text("Memory Usage: %.1f%%", memory_history.back());
ImTui::PlotLines("##memory", memory_history.data(), memory_history.size(),
0, nullptr, 0.0f, 100.0f, ImVec2(0, 40));
}
ImTui::Separator();
// System information
ImTui::Text("Uptime: 2 days, 4 hours");
ImTui::Text("Load Average: 0.45, 0.38, 0.32");
if (ImTui::Button("Refresh")) {
// Refresh logic
}
ImTui::SameLine();
if (ImTui::Button("Clear History")) {
cpu_history.clear();
memory_history.clear();
}
}
ImTui::End();
}
};
int main() {
IMTUI_CHECKVERSION();
ImTui::CreateContext();
auto screen = ImTui_ImplNcurses_Init(true);
ImTui_ImplText_Init();
SystemMonitor monitor;
bool running = true;
while (running) {
ImTui_ImplNcurses_NewFrame();
ImTui_ImplText_NewFrame();
ImTui::NewFrame();
monitor.update();
monitor.render();
// Main menu
if (ImTui::BeginMainMenuBar()) {
if (ImTui::BeginMenu("File")) {
if (ImTui::MenuItem("Exit", "Ctrl+Q")) {
running = false;
}
ImTui::EndMenu();
}
ImTui::EndMainMenuBar();
}
ImTui::Render();
ImTui_ImplText_RenderDrawData(ImTui::GetDrawData(), screen);
ImTui_ImplNcurses_DrawScreen();
}
ImTui_ImplText_Shutdown();
ImTui_ImplNcurses_Shutdown();
ImTui::DestroyContext();
return 0;
}
Debug & Diagnostic Tool
#include "imtui/imtui.h"
#include "imtui/imtui-impl-ncurses.h"
#include <map>
#include <string>
#include <sstream>
class DebugConsole {
private:
std::vector<std::string> log_messages;
std::map<std::string, float> variables;
char input_buffer[256] = "";
public:
DebugConsole() {
variables["frame_time"] = 16.67f;
variables["fps"] = 60.0f;
variables["memory_mb"] = 256.0f;
log("Debug console initialized");
}
void log(const std::string& message) {
log_messages.push_back(message);
if (log_messages.size() > 1000) {
log_messages.erase(log_messages.begin());
}
}
void set_variable(const std::string& name, float value) {
variables[name] = value;
log("Variable '" + name + "' set to " + std::to_string(value));
}
void render() {
ImTui::SetNextWindowPos(ImVec2(1, 1), ImGuiCond_Once);
ImTui::SetNextWindowSize(ImVec2(78, 22), ImGuiCond_Once);
if (ImTui::Begin("Debug Console")) {
// Variable watch
if (ImTui::CollapsingHeader("Variables", ImGuiTreeNodeFlags_DefaultOpen)) {
for (auto& [name, value] : variables) {
ImTui::Text("%-20s: %.3f", name.c_str(), value);
ImTui::SameLine();
if (ImTui::SmallButton(("Edit##" + name).c_str())) {
// Open edit dialog
}
}
}
ImTui::Separator();
// Log viewer
if (ImTui::CollapsingHeader("Log", ImGuiTreeNodeFlags_DefaultOpen)) {
ImTui::BeginChild("LogScrolling", ImVec2(0, 120), false, ImGuiWindowFlags_HorizontalScrollbar);
for (const auto& message : log_messages) {
ImTui::Text("%s", message.c_str());
}
if (ImTui::GetScrollY() >= ImTui::GetScrollMaxY()) {
ImTui::SetScrollHereY(1.0f);
}
ImTui::EndChild();
}
ImTui::Separator();
// Command input
ImTui::Text("Command:");
ImTui::SameLine();
if (ImTui::InputText("##command", input_buffer, sizeof(input_buffer),
ImGuiInputTextFlags_EnterReturnsTrue)) {
process_command(input_buffer);
input_buffer[0] = '\0';
ImTui::SetKeyboardFocusHere(-1);
}
ImTui::SameLine();
if (ImTui::Button("Execute")) {
process_command(input_buffer);
input_buffer[0] = '\0';
}
ImTui::SameLine();
if (ImTui::Button("Clear Log")) {
log_messages.clear();
}
}
ImTui::End();
}
private:
void process_command(const std::string& command) {
log("> " + command);
std::istringstream iss(command);
std::string cmd;
iss >> cmd;
if (cmd == "set") {
std::string var_name;
float value;
if (iss >> var_name >> value) {
set_variable(var_name, value);
} else {
log("Usage: set <variable> <value>");
}
} else if (cmd == "get") {
std::string var_name;
if (iss >> var_name) {
auto it = variables.find(var_name);
if (it != variables.end()) {
log(var_name + " = " + std::to_string(it->second));
} else {
log("Variable '" + var_name + "' not found");
}
} else {
log("Usage: get <variable>");
}
} else if (cmd == "help") {
log("Available commands:");
log(" set <var> <value> - Set variable value");
log(" get <var> - Get variable value");
log(" help - Show this help");
log(" clear - Clear log");
} else if (cmd == "clear") {
log_messages.clear();
} else if (!cmd.empty()) {
log("Unknown command: " + cmd + " (type 'help' for commands)");
}
}
};
Ecosystem
Backends
- ncurses: Standard backend for Unix/Linux environments
- Windows Console: Windows environment support
- SDL: Potential future GUI support
Related Projects
- Dear ImGui: Original ImGui library
- ImPlot: Plotting functionality extension
- ImGuiColorTextEdit: Text editor functionality
Advantages
- Low learning curve: Familiar API for ImGui users
- Immediate mode: No complex state management required
- Ideal for debugging: Excellent for real-time parameter adjustment
- Lightweight: Minimal dependencies
- Cross-platform: Windows, Linux, macOS support
Limitations
- Limited widgets: Some functionality restricted by ncurses constraints
- Performance: Higher CPU usage due to per-frame rendering
- Customization: Limited theme and style customization
- Complex layouts: Advanced layout features are limited
Comparison with Other Libraries
Feature | ImTui | FTXUI | ncurses |
---|---|---|---|
Paradigm | Immediate Mode | Declarative | Procedural |
Learning Curve | Low (ImGui experience) | Medium | High |
Debug Use | ★★★★★ | ★★★☆☆ | ★★☆☆☆ |
Performance | ★★☆☆☆ | ★★★★☆ | ★★★★★ |
Customizability | ★★☆☆☆ | ★★★★☆ | ★★★★★ |
Summary
ImTui is an innovative library that brings Dear ImGui's ease of use to terminal environments. It excels particularly in debug tools, prototyping, and real-time monitoring application development, enabling rapid development that leverages the benefits of immediate mode GUI. With ImGui experience, you can immediately start productive TUI application development.