raygui: an immediate-mode GUI for raylib tools, in one header
A simple and easy-to-use immediate-mode gui library
At a glance
- What is it?
- raygui is a single-file, header-only C library that draws buttons, sliders and panels straight into a raylib frame. It suits internal tools and editors, not consumer applications with complex state.
- Who is it for?
- Adopt raygui if you are building an editor, debug panel or asset tool on top of raylib and you want the UI to live in the same draw loop as your scene, with no widget objects to own or free. Do not adopt it if you need accessibility, text layout for long documents, or a UI that survives independently of the render loop.
- Can I use it commercially?
- Yes. Zlib is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 9 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What raygui solves, and who it is actually for
Most GUI toolkits keep a tree of widget objects alive between frames. You create a button, it persists, you mutate it, and you destroy it. raygui does the opposite: nothing persists. The README describes it as an immediate-mode GUI library with no retained data, and says it was originally inspired by Unity IMGUI. Each frame you call GuiButton, GuiSlider or GuiCheckBox with the current state, and the function both draws the control and returns what the user did with it.
That model fits a narrow audience well. The README states that raygui is intended for tools development and points to published tools on raylibtech.itch.io as evidence of that use. If you are writing a level editor, a sprite packer, a curve editor or an in-game debug overlay, the state you care about already exists in your program as a float, a bool or an index. You do not need a widget object to hold it. You pass the address and raygui edits it in place.
It is a poor fit for anything where the UI has its own lifecycle. Dialog stacks, undo of UI state, and screens that must be rebuilt from a serialized description all become manual work, because raygui will not remember a control between frames. The library is also positioned as an auxiliary module for raylib, so the drawing is raylib drawing: plain rectangles, wide borders, simple colors. Applications that need platform-native look and feel are outside its scope.
How the single-header mechanism works in practice
raygui is one file, src/raygui.h, containing declarations and implementation. The README is explicit about the rule: define RAYGUI_IMPLEMENTATION before including raygui.h in exactly one compilation unit. Every other file that needs the API includes raygui.h without that define. Get this wrong in two translation units and you get duplicate symbol errors at link time.
The header still depends on raylib at runtime. raygui draws through raylib primitives and reads raylib input, so a raylib context must exist before any control is called. The README carries a warning that the master branch of raygui is always aligned with the master branch of raylib and with the raylibtech tools, which means a mismatch between a released raygui and an older raylib is a real risk rather than a theoretical one.
State flows one way per frame. You read your own variables, pass them by address to a Gui* function, and the function writes back if the user interacted. Version 5.0 changed this contract: the README states that raygui 5.0 introduces API-breaking changes and that all functions now return a result value. Code written against 4.0 that ignored return values will still compile in many cases but will not see the new signals.
Styling is separate from layout. A default style loads at runtime, additional styles live in the styles directory, and GuiLoadStyle() swaps them. Icons are compiled in: the README describes an embedded array of 512 icons at 16x16 pixels, 1 bit per pixel, 4096 bytes total, addressed by prefixing #iconId# inside any control's text.
Installing raygui and drawing your first button
There is no package manager step in the README. You copy src/raygui.h into your project, next to raylib, and compile it as part of your build. The README's code sample is the shortest working path, and it assumes raylib is already available to the compiler.
#include "raylib.h"
#define RAYGUI_IMPLEMENTATION
#include "raygui.h"The define comes first, and only in this file. If a second file includes raygui.h, it includes it without the define.
Inside the main loop, the control call and the state update are the same statement. The README's example draws a button that toggles a flag, then opens a message box when the flag is set.
bool showMessageBox = false;
if (GuiButton((Rectangle){ 24, 24, 120, 30 }, "#191#Show Message")) showMessageBox = true;
if (showMessageBox)
{
int btnActive = -1;
GuiMessageBox((Rectangle){ 85, 70, 250, 100 },
"#191#Message Box", "Hi! This is a message!", "Nice;Cool", &btnActive);
if (btnActive >= 0) showMessageBox = false;
}Two details in that snippet carry the whole idiom. The #191# prefix is an icon id embedded in the label string, and the message box reports which button was pressed through an int pointer rather than a return value. Note the separator in "Nice;Cool": raygui splits button labels on semicolons.
If you need a shared library instead of a header, the README gives per-platform build commands. The Linux one is representative.
mv src/raygui.h src/raygui.c
gcc -o raygui.so src/raygui.c -shared -fpic -DRAYGUI_IMPLEMENTATION -lraylib -lGL -lm -lpthread -ldl -lrt -lX11
mv src/raygui.c src/raygui.hThe rename is not cosmetic. The implementation is only compiled when the file is treated as a .c translation unit, and the second mv restores the header so the rest of your project keeps including it by its documented name.
For a first real use, the repository's examples/controls_test_suite directory is the reference: it exercises the controls in one window, and the README's screenshot of that suite is what you should see when it runs.
Where raygui breaks down
The immediate-mode contract has a cost that the README does not dwell on. Because nothing is retained, any behavior that depends on remembering the previous frame is your responsibility. Detecting a double click, tracking focus across a tab change, or restoring a scroll position after a panel is hidden all require you to keep that state yourself and feed it back in. The library gives you ScrollPanel and TabBar controls, but the persistence behind them is yours.
The versioning story is the sharper edge. raygui 4.0 shipped in September 2023 and 5.0 in July 2026, so the gap between major releases is measured in years, and 5.0 changed every function's return contract. The README's own warning about master tracking master means that if you pin a raygui release and later upgrade raylib, you may be on an unsupported combination. There is no compatibility matrix in the README; the instruction is simply to use the latest of both.
Text handling is the third limit. raygui is a drawing library, not a text engine. The README lists TextBox, ValueBox and TextInputBox as controls, but there is no mention of bidirectional text, complex script shaping, or rich text layout. Long-form text editing, right-to-left languages, and anything resembling a document editor are outside what the documentation claims.
Finally, the tooling around styles and icons is external. rGuiStyler, rGuiIcons and rGuiLayout are separate downloads from raylibtech.itch.io. If you want a custom theme or a trimmed icon set, that work happens in another application, not in the repository.
raygui versus building directly on raylib, and versus Dear ImGui
The most common question is whether to use raygui at all when raylib already draws rectangles and reads the mouse. The difference is the control layer: raygui supplies roughly 25 controls, from Button, Slider and CheckBox up through ListView, ColorPicker and MessageBox, plus containers like WindowBox and ScrollPanel. Writing those by hand in raylib is possible, and for two or three controls it is often less work than adding a dependency. The crossover is somewhere around the point where you need a combo box with a scrollable popup, because that is where hand-rolled raylib input handling starts to sprawl.
The more interesting comparison is with Dear ImGui, the other well-known immediate-mode C++ library. The repository does not compare them, so the difference has to be read off the design. raygui is C, single-header, and draws in raylib's visual style with raylib's own primitives. Dear ImGui is C++ and brings its own renderer backends. If your project is C and already linked against raylib, raygui adds one file and no new rendering path. If your project is C++ with an existing graphics stack, raygui's raylib dependency is the deciding constraint, and its standalone mode, which the README lists as a feature for other graphic libraries, is the escape hatch rather than the default.
The README also lists bindings indirectly through the shared-library build instructions, which exist so that other languages can call into raygui. That is the route for users who are not writing C.
Maintenance, licence and the upgrade bill
The repository is not archived, and the last push was on 2026-09-21, two days before this writing. The release cadence is slow and deliberate: 3.6 in May 2023, 4.0 in September 2023, and 5.0 in July 2026. That means an upgrade is an event rather than a routine. Budget for reading HISTORY.md and the release notes before moving a project from 4.0 to 5.0, because the return-value change touches every call site in your UI code.
The licence is the zlib/libpng licence, which the README describes as unmodified and OSI-certified. For most projects that is the least restrictive end of the spectrum: it permits use in closed-source software and asks for attribution rather than source disclosure. It is not the same as public domain, and the README does not discuss trademark or patent terms. That is a question for your own legal review, not for this article.
The hidden maintenance cost is the raylib coupling. Because raygui master tracks raylib master, upgrading raylib can force a raygui upgrade, which can force an API migration. Pinning both and upgrading them together is the only pattern the documentation supports.
Editorial conclusion
Adopt raygui if you are building an editor, debug panel or asset tool on top of raylib and you want the UI to live in the same draw loop as your scene, with no widget objects to own or free. Do not adopt it if you need accessibility, text layout for long documents, or a UI that survives independently of the render loop. Before committing, verify three things against the master branch: that your raylib version matches the one raygui targets, that the v5.0 return-value API is what your code expects, and that the controls you need actually exist in the list. The examples/controls_test_suite directory is the fastest way to see every control at once.
Frequently asked questions
What is raygui?
raygui is a simple, immediate-mode GUI library written in C, designed as an auxiliary module for raylib. It provides more than 25 controls, a styling system and an embedded icon set, and is distributed as a single header file, raygui.h.
How do I install raygui?
There is no package manager step. You copy src/raygui.h into your project, define RAYGUI_IMPLEMENTATION before including it in exactly one compilation unit, and compile it alongside raylib. The README also gives shared-library build commands for Windows, Linux and macOS.
How do I use raygui?
Call Gui* functions inside your raylib draw loop, passing your own variables by address. Each call draws the control and reports interaction, so nothing is retained between frames. The README's sample shows GuiButton toggling a flag and GuiMessageBox reporting the pressed button through an int pointer.
what is raygui
It is an immediate-mode GUI library for C, inspired by Unity IMGUI and intended for tools development. It draws using raylib's graphic style but the README states it can be adapted to other engines and frameworks.
raygui vs raylib
They are not alternatives. raylib is the graphics library; raygui is an auxiliary module that draws controls through raylib primitives and reads raylib input. raygui cannot run without a raylib context, and the README warns that master branches of both are kept aligned.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/raysan5-raygui)