Handle and thread
RaylibHandle is the entry point for almost every raylib operation. Together with RaylibThread, it
is returned by raylib::init().build(). The two-value return enforces two invariants at the type
level: there can only be one active window at a time (single-init), and drawing can only happen on
the thread that owns the handle.
RaylibHandle owns the window and the OpenGL context. RaylibThread is a zero-sized marker token
that proves you are on the main thread. You pass &thread into begin_drawing and other
thread-sensitive calls; the borrow checker ensures they are never called from a background thread.
API surface
RaylibHandle— the main API handle; returned alongsideRaylibThreadfrom.build().RaylibThread— main-thread proof token;!Send.RaylibBuilder— builder for the window; obtained fromraylib::init().raylib::init()— the only entry point; returns aRaylibBuilder.RaylibHandle::window_should_close— returnstruewhen the user requests quit (window X,Escape, etc.).RaylibHandle::begin_drawing— opens a drawing frame; returns aRaylibDrawHandleguard that commits the frame on drop.
Example
The following shows the canonical init-loop-draw pattern, highlighting where the handle and thread token appear:
extern crate raylib;
use raylib::prelude::*;
fn main() {
// init() returns a RaylibBuilder; .build() opens the window.
// The two return values are the handle (rl) and the thread token (thread).
let (mut rl, thread) = raylib::init()
.size(640, 480)
.title("Handle and thread demo")
.build();
while !rl.window_should_close() {
// begin_drawing takes &thread — the borrow checker ensures this is
// the main thread. The returned guard commits the frame on drop.
let mut d = rl.begin_drawing(&thread);
d.clear_background(Color::RAYWHITE);
d.draw_text("RaylibHandle in action", 20, 20, 20, Color::DARKGRAY);
}
// rl is dropped here, tearing down the window and GL context.
}
Gotchas
RaylibThreadis!Send— never put it in aMutex,Arc, orthread::spawnpayload. The compiler will reject the attempt; this is intentional.- Single-init — calling
raylib::init().build()while an existingRaylibHandleis live will panic. raylib’s C layer maintains global window state; there is no way to have two windows in one process. - Teardown order — window teardown happens when
RaylibHandleis dropped. If youmem::forgetthe handle, raylib’s GL context leaks. Let Rust’s normal drop order handle cleanup; do not try to tear down the window manually.
See also
core-concepts/raii-and-resources.md— how all raylib resources follow RAII semantics.modules/window-and-drawing.md— the full window configuration and drawing API.- docs.rs
RaylibHandle