sola-raylib
sola-raylib is an actively maintained Rust bindings and wrapper for raylib 6.0. It currently targets Rust toolchain version 1.78 or higher.
- View the project on crates.io: https://crates.io/crates/sola-raylib
- View the docs: https://docs.rs/sola-raylib/latest/sola_raylib/
Versioning: sola-raylib's major version tracks raylib's major version — 5.x binds raylib 5.5, 6.x binds raylib 6.0, and so on. Minor and patch numbers are sola-raylib's own (raylib doesn't follow strict semver, so this project doesn't try to mirror it beyond the major).
This project is a fork of github.com/raylib-rs/raylib-rs from commit 91bcb492c61dc067945d59357ca6def0d83fcb2c (v5.5.1 release), which was a fork of github.com/deltaphc/raylib-rs.
Check out the examples directory to find usage examples. See CHANGELOG.md for the 6.x changes, including breaking signature changes and the new APIs wrapped from raylib 6.0.
sola-raylib development happens on main. This README.md covers what's in
main. Be sure to view the tag version of the repository if you want to find
details on a specific version.
The latest released version on crates.io is 6.1.0 (binds raylib 6.0).
Pull from GitHub if you want the latest main:
raylib = { package = "sola-raylib", git = "https://github.com/brettchalupa/sola-raylib.git" }
Features / Bugs
Though this binding tries to stay close to the simple C API, it makes some changes to be more idiomatic for Rust.
- Resources are automatically cleaned up when they go out of scope (or when
std::mem::dropis called). This is essentially RAII. This means that "Unload" functions are not exposed (and not necessary unless you obtain aWeakresource using make_weak()). - Most of the Raylib API is exposed through
RaylibHandle, which is for enforcing that Raylib is only initialized once, and for making sure the window is closed properly. RaylibHandle has no size and goes away at compile time. Because of mutability rules, Raylib-rs is thread safe! - A
RaylibHandleandRaylibThreadare obtained through through theinit()function which will allow you tobuildup some window options before initialization (replacesset_config_flags). RaylibThread should not be sent to any other threads, or used in a any syncronization primitives (Mutex, Arc) etc. - Manually closing the window is unnecessary, because
CloseWindowis automatically called whenRaylibHandlegoes out of scope. Model::set_material,Material::set_shader, andMaterialMap::set_texturemethods were added since one cannot set the fields directly. Also enforces correct ownership semantics.Font::from_data,Font::set_chars, andFont::set_texturemethods were added to create aFontfrom loadedCharInfodata.SubTextandFormatTextare omitted, and are instead covered by Rust's string slicing and Rust'sformat!macro, respectively.
Why use Rust with Raylib instead of C?
There are many benefits to coding games with Raylib using Rust instead of C:
- Memory safety guarantees from the Rust compiler in the code you write.
- Best-in-class developer experience with
cargoand Rust's language server protocol (LSP). - Lots of great Rust packages for game development and systems programming on crates.io.
- Easier cross-platform compiling.
Installation
Supported Platforms
sola-raylib is focused on supporting Windows, Linux, macOS, and Web targets.
The table below shows which core APIs are supported for which platforms:
| API | Windows | Linux | macOS | Web |
|---|---|---|---|---|
| core | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
| rgui | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | ❔ |
| rlgl | :heavy_check_mark: | :x: | :x: | ❔ |
Build Dependencies
Requires glfw, cmake, and curl. Tips on making things work smoothly on all platforms is appreciated. Follow instructions for building raylib for your platform here
- Add the dependency to your
Cargo.toml:
[]
= "6.0"
Then in your code, use it as sola_raylib:
use *;
Drop-in replacement for raylib-rs
If you're migrating an existing raylib-rs project and don't want to touch
every use raylib::... statement, use Cargo's package rename so the crate is
still imported as raylib in your source code:
[]
= { = "sola-raylib", = "6.0" }
With that line, all your existing raylib code keeps working. The ./examples in
this repository use this style.
- Start coding!
use *;
Building for the web (wasm)
sola-raylib targets wasm32-unknown-emscripten so games can run in the browser.
The link flags raylib needs (-sUSE_GLFW=3, -sASYNCIFY=1,
-sFORCE_FILESYSTEM=1, -sSUPPORT_LONGJMP=wasm,
-sEXPORTED_RUNTIME_METHODS=..., -sALLOW_MEMORY_GROWTH=1) live in your
project's .cargo/config.toml: cargo silently drops cargo:rustc-link-arg from
rlib build scripts, so a sys crate can't inject them. raylib's own C compiles
cleanly under rustc 1.93+'s default link ABI; no sys-side cflag tweaks are
needed.
There is also game_loop::run, a cross-platform game-loop helper that
registers a per-frame closure with emscripten_set_main_loop_arg on the web and
drives a normal while-loop natively. Same source for both targets.
The full recipe (asset bundling, save data, audio, deploy) lives in
book/src/web.md. Reference example:
examples/hello_raylib.rs; copyable config:
examples/.cargo/config.toml. just build-web
then just serve-web opens it at http://localhost:3535.
Cross-compiling using cross
Cross compiling with sola-raylib can be made easier with cross. See the upstream raylib-rs wiki for a writeup that should still largely apply.
Tech Notes
- Structs holding resources have RAII/move semantics, including:
Image,Texture2D,RenderTexture2D,Font,Mesh,Shader,Material, andModel. Wave,Sound,Music, andAudioStreamhave lifetimes bound toAudioHandle.- Functions dealing with string data take in
&strand/or return an ownedString, for the sake of safety. The exception to this is the gui draw functions which take &CStr to avoid per frame allocations. Therstr!macro helps make this easy. - In C,
LoadFontDatareturns a pointer to a heap-allocated array ofCharInfostructs. In this Rust binding, said array is copied into an ownedVec<CharInfo>, the original data is freed, and the owned Vec is returned. - In C,
LoadDroppedFilesreturns a pointer to an array of strings owned by raylib. Again, for safety and also ease of use, this binding copies said array into aVec<String>which is returned to the caller. - Linking is automatic, though I've only tested on Windows 10, Ubuntu, and MacOS 15. Other platforms may have other considerations.
- OpenGL 3.3, 2.1, and ES 2.0 may be forced via adding
["opengl_33"],["opengl_21"]or["opengl_es_20]to thefeaturesarray in your Cargo.toml dependency definition.
Cargo features
Every Cargo feature exposed by sola-raylib is listed here. The safe crate
forwards each name through to sola-raylib-sys, so you can enable them on
either crate and the effect is the same.
Build / linking
| Feature | Default | Effect |
|---|---|---|
bindgen |
yes | Run bindgen at build time to produce FFI bindings. Disable to supply a hand-rolled bindings.rs (for platforms bindgen can't target). |
nobuild |
no | Skip compiling and linking raylib entirely. For docs.rs and headless setups; you are then responsible for linking raylib yourself. |
Platform & rendering backend
| Feature | Default | Effect |
|---|---|---|
wayland |
no | Build raylib's GLFW with native Wayland support on Linux. Requires the system glfw-devel (CMake config files), not just the runtime; see "Building for Wayland on Linux" below. Without this feature, GLFW uses X11/XWayland. |
sdl |
no | Use the SDL platform backend instead of GLFW. Build script auto-picks SDL3 if present, else SDL2, via pkg-config. Install with sudo dnf install SDL2-devel (Fedora), sudo apt install libsdl2-dev (Debian/Ubuntu), brew install sdl2 (macOS). |
opengl_33 |
no | Force OpenGL 3.3 backend. |
opengl_21 |
no | Force OpenGL 2.1 backend. |
opengl_es_20 |
no | Force OpenGL ES 2.0 backend. |
opengl_es_30 |
no | Force OpenGL ES 3.0 backend. |
software_render |
no | Experimental; see "Experimental raylib 6.0 platform flags". |
platform_memory |
no | Experimental; see "Experimental raylib 6.0 platform flags". |
platform_web_rgfw |
no | Experimental; see "Experimental raylib 6.0 platform flags". |
Behavior toggles
| Feature | Default | Effect |
|---|---|---|
custom_frame_control |
no | Enable raylib's SUPPORT_CUSTOM_FRAME_CONTROL so you drive frame timing yourself (call SwapScreenBuffer, PollInputEvents manually). |
noscreenshot |
no | Disable raylib's built-in F12-screenshot keybind. Implemented by pre-defining SUPPORT_SCREEN_CAPTURE=0 directly on the C compile line, leaving the rest of raylib's SUPPORT_* defaults intact. (Earlier 6.0 builds routed this through CMake's CUSTOMIZE_BUILD switch and broke rendering on Linux; see issue #40, fixed in 6.1.) |
Interop
| Feature | Default | Effect |
|---|---|---|
with_serde |
no | Derive serde::Serialize / Deserialize on the public types via serde + serde_json. |
convert_mint |
no | Implement conversions to/from mint math types. |
Removed in 6.1: the
nogiffeature is gone. Raylib 6.0 dropped its built-in GIF recorder upstream, sonogifhad no effect, just the harmful side-effect of triggering the sameCUSTOMIZE_BUILDregression asnoscreenshot. If you previously listed it in your Cargo.toml, just remove it.
Platform-Specific Notes
Windows
On Windows, your compiled binary will show a log window by default. If you want
to hide this, add the following to your main.rs:
Experimental raylib 6.0 platform flags
sola-raylib 6.0 exposes three feature flags for raylib 6.0's new backends. All three are experimental upstream, shipped with known gaps in raylib 6.0 itself. We surface them for opt-in use, but what actually renders or links is whatever raylib's C side supports at HEAD. Expect rough edges.
-
software_render: compiles raylib with the CPUrlswsoftware rasterizer. Must be combined with thesdlfeature on Linux/macOS because rlsw is not compatible with raylib's default GLFW desktop backend (confirmed upstream in raylib#5664; enabling onlysoftware_renderproduces a black window). Thesdlfeature needs SDL dev headers installed at build time; raylib prefers SDL3 and falls back to SDL2, and ourbuild.rsauto-detects which is present viapkg-config. Install withsudo dnf install SDL2-develon Fedora,sudo apt install libsdl2-devon Debian/Ubuntu,brew install sdl2on macOS. Typical usage:# Linux or macOS, with SDL installed: cargo add sola-raylib --features sdl,software_renderOr to try it from this repo:
just example-sw hello_raylib.Windows would need the
rcore_desktop_win32native backend (not yet wired in sola-raylib). -
platform_memory: compiles thePLATFORM=Memoryheadless framebuffer backend. The backend builds and links; the APIs for reading the framebuffer back out (fromrlsw.h, e.g.swGetColorBuffer) are not yet wrapped in the safe crate, so there's no usable headless-capture path today. -
platform_web_rgfw: swaps the Emscripten/GLFW web backend for RGFW (PLATFORM=WebRGFW) when cross-compiling towasm32-unknown-emscripten. Only meaningful with an emscripten build loop.
If you're evaluating one of these for production, test on your target platform first and expect to track upstream raylib for fixes.
Drop ordering
Resources like Texture2D, RenderTexture2D, Font, Model, Mesh, and
Shader hold GPU handles and free them in their Drop impl. RaylibHandle's
Drop calls CloseWindow(), which tears down the GL context. GPU resources
must drop before the RaylibHandle — otherwise their unload calls run against
a dead context and segfault.
Rust drops local variables in reverse declaration order, and struct fields in
declaration order. So if you hold both resources and RaylibHandle in the
same struct, declare rl last:
The same rule applies when rl and resources are locals in the same function:
declare rl first so it drops last.
Audio resources (Wave, Sound, Music, AudioStream) are lifetime-bound to
RaylibAudio, so the borrow checker enforces their ordering for you — no
discipline required.
Building from source
- Clone repository:
git clone --recurse-submodules cargo build
If building for Wayland on Linux
- Install these packages:
libglfw3-dev wayland-devel libxkbcommon-devel wayland-protocols wayland-protocols-devel libecm-dev - Enable wayland by adding
features=["wayland"]to your dependency definition
Note that the packages may not be a comprehensive list, please add details for your distribution or expand on these packages if you believe this to be incomplete.
Extras
- In addition to the base library, there is also a convenient
easemodule which contains various interpolation/easing functions ported from raylib'seasings.h, as well as aTweenstruct to assist in using these functions. - Equivalent math and vector operations, ported from
raymath.h, areimpled on the various Vector and Matrix types. Operator overloading is used for more intuitive design.
Contributing & Support
Contributions are welcome. See CONTRIBUTING.md for more details.
See DEVELOPING.md for how to work with this repo locally.