Convert Figma logo to code with AI

Immediate-Mode-UI logoNuklear

A single-header ANSI C immediate mode cross-platform GUI library

9,077
542
9,077
252

Top Related Projects

60,541

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies

3,379

A simple and easy-to-use immediate-mode gui library

13,679

A single-header ANSI C gui library

10,698

Simple and portable (but not inflexible) GUI library in C that uses the native GUI technologies of each platform it supports.

3,408

A tiny immediate-mode UI library

16,094

Embedded graphics library to create beautiful UIs for any MCU, MPU and display type.

Quick Overview

Nuklear is a single-header ANSI C immediate mode GUI library. It's designed to be easily embedded into applications, providing a simple and lightweight solution for creating graphical user interfaces. Nuklear is highly portable and can be integrated into various graphics APIs and platforms.

Pros

  • Lightweight and easy to integrate (single-header file)
  • Highly portable across different platforms and graphics APIs
  • Customizable and flexible, allowing for extensive styling options
  • No external dependencies, making it easy to include in projects

Cons

  • Limited built-in widgets compared to more comprehensive GUI libraries
  • Immediate mode GUI can be less intuitive for developers used to retained mode systems
  • Documentation could be more extensive and user-friendly
  • Performance may not be optimal for very complex UIs or large applications

Code Examples

  1. Creating a simple window:
struct nk_context ctx;
nk_init_fixed(&ctx, memory, MAX_MEMORY, &font);

if (nk_begin(&ctx, "Demo", nk_rect(50, 50, 200, 200),
    NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
    NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
{
    nk_layout_row_dynamic(&ctx, 30, 1);
    nk_label(&ctx, "Hello, Nuklear!", NK_TEXT_LEFT);
}
nk_end(&ctx);
  1. Adding a button and handling clicks:
if (nk_button_label(&ctx, "Click me!"))
{
    printf("Button clicked!\n");
}
  1. Creating a simple input field:
static char text[256] = "Input text here";
nk_layout_row_dynamic(&ctx, 25, 1);
nk_edit_string(&ctx, NK_EDIT_SIMPLE, text, sizeof(text) - 1, nk_filter_default);

Getting Started

  1. Download the nuklear.h header file from the GitHub repository.
  2. Include the header in your project:
    #define NK_IMPLEMENTATION
    #include "nuklear.h"
    
  3. Initialize Nuklear context:
    struct nk_context ctx;
    nk_init_fixed(&ctx, memory, MAX_MEMORY, &font);
    
  4. In your main loop, begin and end Nuklear frames:
    nk_input_begin(&ctx);
    // Process input events here
    nk_input_end(&ctx);
    
    if (nk_begin(&ctx, "Window Title", nk_rect(50, 50, 200, 200), 0))
    {
        // Add your UI elements here
    }
    nk_end(&ctx);
    
    // Render Nuklear commands
    

Competitor Comparisons

60,541

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies

Pros of ImGui

  • More feature-rich and actively maintained
  • Extensive documentation and examples
  • Wider community support and adoption

Cons of ImGui

  • Larger codebase and potentially higher memory footprint
  • C++ only, which may limit integration in some projects

Code Comparison

ImGui:

ImGui::Begin("My Window");
if (ImGui::Button("Click me!"))
    doSomething();
ImGui::Text("Hello, world %d", 123);
ImGui::End();

Nuklear:

if (nk_begin(ctx, "My Window", nk_rect(50, 50, 200, 200), 0))
{
    if (nk_button_label(ctx, "Click me!"))
        doSomething();
    nk_label(ctx, "Hello, world 123", NK_TEXT_LEFT);
}
nk_end(ctx);

Key Differences

  • ImGui is C++ based, while Nuklear is written in C
  • ImGui offers more built-in widgets and features
  • Nuklear has a smaller footprint and can be easier to integrate in some cases
  • ImGui has better support for custom rendering and styling
  • Nuklear provides more low-level control over the UI elements

Both libraries are popular choices for immediate mode GUI development, with ImGui being more feature-rich and widely adopted, while Nuklear offers a lighter-weight alternative with C language support.

3,379

A simple and easy-to-use immediate-mode gui library

Pros of raygui

  • Lightweight and easy to integrate with raylib
  • Designed specifically for game development
  • Supports both immediate mode and retained mode GUI

Cons of raygui

  • Less feature-rich compared to Nuklear
  • Limited to C programming language
  • Smaller community and ecosystem

Code Comparison

raygui:

GuiButton((Rectangle){ 25, 25, 125, 30 }, "Button");
if (GuiButton((Rectangle){ 25, 60, 125, 30 }, "Click me!")) {
    // Handle button click
}

Nuklear:

if (nk_button_label(ctx, "Button")) {
    // Handle button click
}
nk_layout_row_dynamic(ctx, 30, 1);
if (nk_button_label(ctx, "Click me!")) {
    // Handle button click
}

Both libraries offer simple ways to create buttons, but Nuklear provides more layout control out of the box. raygui's syntax is more straightforward, while Nuklear requires more setup but offers greater flexibility.

raygui is ideal for quick prototyping and game development with raylib, while Nuklear is better suited for complex, cross-platform applications requiring extensive GUI customization.

13,679

A single-header ANSI C gui library

Pros of Nuklear (vurtun)

  • More active development and recent updates
  • Larger community and more contributors
  • Better documentation and examples

Cons of Nuklear (vurtun)

  • Slightly more complex API
  • Less focus on minimalism and simplicity
  • Potentially higher memory footprint

Code Comparison

Nuklear (vurtun):

struct nk_context ctx;
nk_init_default(&ctx, 0);
if (nk_begin(&ctx, "Demo", nk_rect(50, 50, 200, 200),
    NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
    NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
{
    nk_layout_row_dynamic(&ctx, 30, 1);
    if (nk_button_label(&ctx, "Button"))
        fprintf(stdout, "Button pressed!\n");
}
nk_end(&ctx);

Nuklear (Immediate-Mode-UI):

struct nk_context ctx;
nk_init_default(&ctx, 0);
if (nk_begin(&ctx, "Demo", nk_rect(50, 50, 200, 200), 0))
{
    nk_layout_row_dynamic(&ctx, 30, 1);
    if (nk_button_label(&ctx, "Button"))
        printf("Button pressed!\n");
}
nk_end(&ctx);

The code comparison shows that both versions have similar syntax and structure, with minor differences in window flags and output methods.

10,698

Simple and portable (but not inflexible) GUI library in C that uses the native GUI technologies of each platform it supports.

Pros of libui

  • Native look and feel across platforms (Windows, macOS, Linux)
  • Simple and straightforward API for creating GUI applications
  • Lightweight and minimal dependencies

Cons of libui

  • Limited widget set compared to Nuklear
  • Less flexibility in customizing UI appearance
  • Slower development and fewer updates

Code Comparison

libui example:

uiInit(NULL);
uiWindow *window = uiNewWindow("Hello", 300, 200, 0);
uiButton *button = uiNewButton("Click Me");
uiWindowSetChild(window, uiControl(button));
uiControlShow(uiControl(window));
uiMain();

Nuklear example:

struct nk_context ctx;
nk_init_default(&ctx, 0);
if (nk_begin(&ctx, "Hello", nk_rect(50, 50, 200, 200), NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE)) {
    nk_layout_row_static(&ctx, 30, 80, 1);
    if (nk_button_label(&ctx, "Click Me")) {
        // Button clicked
    }
}
nk_end(&ctx);

The code comparison shows that libui has a more straightforward API for creating basic UI elements, while Nuklear offers more fine-grained control over the UI layout and appearance. Nuklear's immediate mode approach allows for more dynamic UI updates, whereas libui follows a more traditional retained mode GUI paradigm.

3,408

A tiny immediate-mode UI library

Pros of microui

  • Extremely lightweight and minimalistic (under 1000 lines of C)
  • Easy to integrate into existing projects due to its simplicity
  • No dependencies, making it highly portable

Cons of microui

  • Limited set of UI elements compared to Nuklear
  • Less customization options and styling capabilities
  • Fewer advanced features like layout systems or complex widgets

Code Comparison

microui:

mu_begin(ctx);
if (mu_button(ctx, "Hello")) {
  printf("Button pressed\n");
}
mu_end(ctx);

Nuklear:

if (nk_begin(ctx, "Window", nk_rect(50, 50, 200, 200),
    NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
    NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
{
    nk_layout_row_static(ctx, 30, 80, 1);
    if (nk_button_label(ctx, "Hello")) {
        printf("Button pressed\n");
    }
}
nk_end(ctx);

The code comparison shows that microui has a simpler API with fewer options, while Nuklear provides more control over window properties and layout. microui's approach is more straightforward, but Nuklear offers greater flexibility and features at the cost of increased complexity.

16,094

Embedded graphics library to create beautiful UIs for any MCU, MPU and display type.

Pros of lvgl

  • More comprehensive widget set and built-in themes
  • Better suited for embedded systems and microcontrollers
  • Active development and regular updates

Cons of lvgl

  • Steeper learning curve due to more complex architecture
  • Larger memory footprint compared to Nuklear

Code Comparison

lvgl example:

lv_obj_t * btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, 100, 50);
lv_obj_center(btn);
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL);

Nuklear example:

if (nk_button_label(ctx, "Click me")) {
    // Button clicked
}

lvgl offers a more object-oriented approach with separate creation and event handling, while Nuklear uses a more immediate-mode style with inline event checking. lvgl's code is more verbose but provides greater flexibility and control over widget properties and behaviors. Nuklear's code is more concise and straightforward, making it easier to quickly prototype simple UIs.

Both libraries have their strengths, with lvgl being more suitable for complex, feature-rich interfaces on embedded systems, and Nuklear excelling in simplicity and lightweight implementation for basic UI needs.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Nuklear

This is a minimal-state, immediate-mode graphical user interface toolkit written in ANSI C and licensed under public domain. It was designed as a simple embeddable user interface for application and does not have any dependencies, a default render backend or OS window/input handling but instead provides a highly modular, library-based approach, with simple input state for input and draw commands describing primitive shapes as output. So instead of providing a layered library that tries to abstract over a number of platform and render backends, it focuses only on the actual UI.

Features

  • Immediate-mode graphical user interface toolkit
  • Single-header library
  • Written in C89 (ANSI C)
  • Small codebase (~18kLOC)
  • Focus on portability, efficiency and simplicity
  • No dependencies (not even the standard library if not wanted)
  • Fully skinnable and customizable
  • Low memory footprint with total control of memory usage if needed / wanted
  • UTF-8 support
  • No global or hidden state
  • Customizable library modules (you can compile and use only what you need)
  • Optional font baker and vertex buffer output
  • Documentation

Building

This library is self-contained in one single header file and can be used either in header-only mode or in implementation mode. The header-only mode is used by default when included and allows including this header in other headers and does not contain the actual implementation.

The implementation mode requires defining the preprocessor macro NK_IMPLEMENTATION in one .c/.cpp file before #includeing this file, e.g.:

#define NK_IMPLEMENTATION
#include "nuklear.h"

IMPORTANT: Every time you include "nuklear.h" you have to define the same optional flags. This is very important; not doing it either leads to compiler errors, or even worse, stack corruptions.

Gallery

screenshot screen screen2 node skinning gamepad

Example

/* init gui state */
struct nk_context ctx;
nk_init_fixed(&ctx, calloc(1, MAX_MEMORY), MAX_MEMORY, &font);

enum {EASY, HARD};
static int op = EASY;
static float value = 0.6f;
static int i =  20;

if (nk_begin(&ctx, "Show", nk_rect(50, 50, 220, 220),
    NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_CLOSABLE)) {
    /* fixed widget pixel width */
    nk_layout_row_static(&ctx, 30, 80, 1);
    if (nk_button_label(&ctx, "button")) {
        /* event handling */
    }

    /* fixed widget window ratio width */
    nk_layout_row_dynamic(&ctx, 30, 2);
    if (nk_option_label(&ctx, "easy", op == EASY)) op = EASY;
    if (nk_option_label(&ctx, "hard", op == HARD)) op = HARD;

    /* custom widget pixel width */
    nk_layout_row_begin(&ctx, NK_STATIC, 30, 2);
    {
        nk_layout_row_push(&ctx, 50);
        nk_label(&ctx, "Volume:", NK_TEXT_LEFT);
        nk_layout_row_push(&ctx, 110);
        nk_slider_float(&ctx, 0, &value, 1.0f, 0.1f);
    }
    nk_layout_row_end(&ctx);
}
nk_end(&ctx);

example

Bindings

There are a number of nuklear bindings for different languages created by other authors. I cannot attest for their quality since I am not necessarily proficient in any of these languages. Furthermore there are no guarantee that all bindings will always be kept up to date:

Credits

Developed by Micha Mettke and every direct or indirect contributor to the GitHub.

Embeds stb_texedit, stb_truetype and stb_rectpack by Sean Barrett (public domain) Embeds ProggyClean.ttf font by Tristan Grimmer (MIT license).

Big thank you to Omar Cornut (ocornut@github) for his imgui library and giving me the inspiration for this library, Casey Muratori for handmade hero and his original immediate-mode graphical user interface idea and Sean Barrett for his amazing single-header libraries which restored my faith in libraries and brought me to create some of my own. Finally Apoorva Joshi for his single-header file packer.

License

Nuklear is avaliable under either the MIT License or public domain. See LICENSE for more info.

Reviewers guide

When reviewing pull request there are common things a reviewer should keep in mind.

Reviewing changes to src/* and nuklear.h:

  • Ensure C89 compatibility.
  • The code should work for several backends to an acceptable degree.
  • Check no other parts of nuklear.h are related to the PR and thus nothing is missing.
  • Recommend simple optimizations.
    • Pass small structs by value instead of by pointer.
    • Use local buffers over heap allocation when possible.
  • Check that the coding style is consistent with code around it.
    • Variable/function name casing.
    • Indentation.
    • Curly bracket ({}) placement.
  • Ensure that the contributor has bumped the appropriate version in clib.json and added their changes to the CHANGELOG.
  • Have at least one other person review the changes before merging.

Reviewing changes to demo/*, example/* and other files in the repo:

  • Focus on getting working code merged.
    • We want to make it easy for people to get started with Nuklear, and any demo and example improvements helps in this regard.
  • Use of newer C features, or even other languages is not discouraged.
    • If another language is used, ensure that the build process is easy to figure out.
  • Messy or less efficient code can be merged so long as these outliers are pointed out and easy to find.
  • Version shouldn't be bumped for these changes.
  • Changes that improves code to be more inline with nuklear.h are ofc always welcome.