Raven.

A GUI library in C.

FileEditRun
Blur
Glass
Glass.
Pop
FlyUp
FlyLeft
Drop
Everything moves.
Raven
Clear
Frosted
Tinted
Three glasses.
Made for tools.
<Window Title="Hello">
<VBox Spacing="12">
<Label>Hello from Raven</Label>
<Button Text="Quit"/>
</VBox>
</Window>
Hello from RavenQuit
A window in six lines.
<!-- main.xmlrs --> <script> fn on_hello(_: Rid, _: &str) { set_text(ui().status, "Hi!"); } </script> <Window Title="Hello"> <Label Name="status"/> <Button OnClicked="{on_hello}"/> </Window>
.xmlc C .xmlc++ C++ .xmlrs Rust .xmlpy Python .xmlgo Go .xmlcs C# .xmlzig Zig .xmllua Lua
One file. Your language.
C11.
8 languages.
Zero dependencies.
1.3 MB.
Vulkan.
Win32. X11.

Raven

A GUI library for editors and tools.

Lightweight, multithreaded, written in C11 with no dependency. Write the interface and its code in one file, in C, C++, Rust, Python, Go, C#, Zig or Lua, and build it with the official IDE.

View on GitHubOne file, any languageThe IDEGet startedOpen source

What you can do

Everything a tool needs.

How it works

A window in a few lines.

Describe the interface in C, in XML, or both. Raven handles windows, layout, painting and the GPU.

1 · Initialize

Rinit(R_BACKEND_VULKAN). Raven opens its own windows and loads Vulkan at run time: nothing to link.

2 · Describe

Build the tree with the C API, write it in XML, or mix both. Every object is a Rid, checked on every call.

3 · Run your loop

One frame per call. A game never waits: while (Rdraw_frame()). A tool sleeps until something changes: while (Rwait_frame(-1.0)).

#include <Raven.h>

static void on_clicked(Rid button, void* user) { Rquit(0); }

int main(void) {
    Rinit(R_BACKEND_VULKAN);
    Rid window = Rwindow_create("Hello", 420, 220, R_WINDOW_DEFAULT);
    Rid box = Rwidget_create(R_WIDGET_VBOX);
    Rwindow_set_content(window, box);

    Rwidget_add_child(box, Rlabel_create("Hello from Raven"));
    Rid quit = Rwidget_add_child(box, Rbutton_create("Quit"));
    Rbutton_set_clicked_callback(quit, on_clicked, NULL);

    while (Rwait_frame(-1.0)) {}
    Rshutdown();
}
<Window Title="Hello" Width="420" Height="220">
  <VBox Spacing="12" Slot.HAlign="Center">
    <Label>Hello from Raven</Label>
    <Button Text="Quit" OnClicked="app.quit"/>
  </VBox>
</Window>

<!-- the same window, loaded with
     Rwindow_create_from_xml_file("hello.xml") -->

New · XMLC

One file. Interface and code.
In your language.

Write the window in XML and its code in <script> beside it. ravenc compiles the XML into your language: your compiler checks every callback and every widget, your usual tools build it, and no XML is read at run time.

<!-- src/main.xmlrs: a whole Rust program -->
<script>
use raven::*;
use std::sync::atomic::{AtomicI32, Ordering};
static CLICKS: AtomicI32 = AtomicI32::new(0);

// OnClicked="{on_hello}" below: checked by rustc
fn on_hello(_sender: Rid, _action: &str) {
    let n = CLICKS.fetch_add(1, Ordering::SeqCst) + 1;
    let text = cstr(&format!("{} clicks", n));
    // ui().status: the widget Name="status"
    unsafe { Rlabel_set_text(ui().status, text.as_ptr()) };
}

fn main() {
    unsafe { Rinit(R_BACKEND_VULKAN) };
    main_create();
    unsafe { while Rdraw_frame() != 0 {} Rshutdown() };
}
</script>
<Window Title="Hello" Width="400" Height="200">
  <VBox Spacing="12" Slot.Padding="24">
    <Label Name="status">Not clicked yet</Label>
    <Button Text="Click me" OnClicked="{on_hello}"/>
  </VBox>
</Window>

Your compiler checks it

OnClicked="{on_hello}" calls a function of your scripts and ui().status is the widget named status. A typo is a compile error, not a silent button.

Errors at their line

The scripts keep their line numbers (#line in C and C++). rustc says main.xmlrs:12, and the IDE opens it there.

Plain code, no glue

Any header, crate or package, no XML escaping, no generated header. Plain .xml stays interpreted with live reload while you design.

# C and C++: CMake
add_executable(hello main.xmlc)
target_link_libraries(hello PRIVATE raven::raven)
raven_target_xmlc(hello)

// Rust: build.rs
fn main() { raven_build::compile("src/main.xmlrs"); }

The official IDE

raven_designer. Design, code, build.

The IDE of Raven, made with Raven. A new project in any of the eight languages builds as it is; the interface is edited visually next to its code; F5 builds and runs it with the tools of the language.

New project, eight languages

C, C++, Rust, Python, Go, C#, Zig or Lua: the main.xml…, the files of the language's own tools (CMakeLists.txt, Cargo.toml, go.mod, .csproj, build.zig) and the translations.

Visual and code, in step

Widgets, tree, live preview, properties and XML show the same document; each <script> opens in a tab of its language. Saving keeps your comments and your layout.

Completion of Raven

The whole API read from the headers, the widgets of the interface (ui.<Name>) and the keys of Rtr("…") while you type.

Build with the real tools

CMake, Cargo, go, dotnet, zig, Python, LuaJIT, with the environment set from the Raven package. Errors of GCC, Clang, MSVC, rustc and Go land on the line of your .xml….

Translations as a table

The CSV files of the project as a grid, one column per language. The preview switches language, right to left included.

Made with Raven

Docking, header bar, text editors, tree views: the IDE uses the public API only. What it does, your tools can do.

Example projects

Real programs to read.

From one window in eight languages to a complete 3D scene editor written in .xmlrs.

The viewport of the Raven Bevy Editor: a blue cube selected with its move gizmo, a sphere, a capsule and a torus on a grid
Rust · .xmlrs · Bevy

Raven Bevy Editor

A visual editor of 3D scenes for Bevy. Its whole interface, and all the code behind it, is one file: editor.xmlrs, about 1,450 lines of Raven XML and Rust, compiled by ravenc when Cargo builds.

  • Hierarchy, inspector, add panel, console, docked panels
  • Gizmos to move, rotate and scale, with snapping
  • Orbit camera, picking, undo of every gesture, scene files
  • Bevy renders the scene into the Raven viewport; a software renderer runs without it

Read the codeeditor.xmlrs

8 languages

One program, eight languages

The same window, a button and a counter translated in English and French, as main.xmlc, .xmlc++, .xmlrs, .xmlpy, .xmlgo, .xmlcs, .xmlzig and .xmllua: exactly what the IDE creates, each built by its own tools.

examples/languages

C · XML

Fourteen programs in C

Node graphs, timelines, docking, glass, text editors, web pages, viewports: below, the ones to read first. Six more in the repo: hello, components, memory, overlay and two viewport demos (Vulkan, OpenGL).

examples/

Get started

Build it, link it.

CMake 3.16+ and a C11 compiler. On Linux, the X11 development package (libx11-dev). The Vulkan headers are downloaded when no SDK is found.

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release
cd build && ctest -C Release --output-on-failure
add_subdirectory(raven)
target_link_libraries(app PRIVATE raven::raven)

License

Open source. Free for anything.

Raven is open source under the Apache License 2.0. No watermark, no paid edition, no royalties: what you make with it is yours, and Raven itself is yours to study, fork and improve.

Every feature

Every widget, every platform, every binding. Nothing is held back, nothing to unlock.

Any project

Personal or commercial, open or closed source. Sell it, ship it, use it at work.

Open code

The whole source is on GitHub. Fork it, patch it, send a pull request.

Get it on GitHubAbout the license

Watch

Raven in motion.

Scroll ↓