Skip to main content

Crate rb-sys

The rb-sys crate provides low-level Rust bindings for the Ruby C API, generated directly from ruby.h headers.

Constraints

  • Direct rb-sys: Use for raw, unsafe access to libruby.
  • Gem Development: For most gem development, prefer higher-level libraries (e.g., Magnus with rb-sys feature). See Development Approaches.
  • Embedding Ruby: Use rb-sys with the link-ruby feature.

Crate Features

The following features can be enabled in your Cargo.toml.

FeatureDescriptionDefault
gemConfigures the crate for building a Ruby gem (e.g., does not link libruby).
link-rubyLinks libruby for embedding the Ruby VM in a Rust binary.
ruby-staticStatically links libruby. Can also be set with the RUBY_STATIC=true env var.
global-allocatorReports Rust memory allocations to the Ruby GC. Recommended for gems.
stable-apiUses Ruby's C-level stable API if available for your Ruby version.
bindgen-rbimplsIncludes internal Ruby implementation types in the generated bindings.
bindgen-deprecated-typesIncludes deprecated Ruby functions and types in the bindings.
gc-stressWraps all Ruby C API functions with rb_gc_start() calls to smoke out GC bugs.

Usage Examples

Ruby Gem Integration

Enable the gem feature (default) and global-allocator for memory reporting.

[dependencies]
rb-sys = { version = "0.9", features = ["global-allocator"] }

Embedding Ruby VM

Enable the link-ruby feature to embed a Ruby VM.

[dependencies]
rb-sys = { version = "0.9", features = ["link-ruby"] }

GC Stress Testing

The gc-stress feature helps find GC safety bugs in native extensions by wrapping every Ruby C API function with calls to rb_gc_start() before and after the real function call. This forces garbage collection at every possible point, making it much more likely to catch issues like:

  • Missing GC guards on Ruby objects
  • Use-after-free of Ruby objects that get collected
  • Incorrect GC marking in custom data types

Enable it during testing:

[dependencies]
rb-sys = { version = "0.9", features = ["gc-stress"] }

The following functions are excluded from wrapping to avoid infinite recursion:

  • rb_gc_* functions (GC internals)
  • ruby_x* functions (memory allocators called during GC)
  • Variadic functions (cannot forward varargs in Rust)
caution

This feature dramatically slows down execution since it triggers a full GC cycle around every Ruby C API call. Only use it for testing, never in production.

Ruby Version Compatibility

rb-sys is compatible with Ruby 2.7 and later. The crate detects the Ruby version at compile time and adapts the bindings accordingly.

For Ruby 3.2 and later, rb-sys provides a ruby_abi_version function that is required for native extensions.

Integration with Magnus

If you're building a Ruby extension, it's recommended to use the Magnus crate on top of rb-sys. Magnus provides a high-level, safe API for interacting with Ruby:

[dependencies]
magnus = { version = "0.7", features = ["rb-sys"] }
rb-sys = "0.9"