mergeNative Fusion Builds

Native Fusion — Rust Interop Reference

Native Fusion is the mechanism that lets you write Rust functions and classes and expose them as first-class BoxLang Built-In Functions (BIFs) and native objects. Everything is statically linked into your final binary — no shared libraries, no FFI boilerplate at the BoxLang call site.

Native Fusion is available in native builds only (--target native). It is not available in WASM targets.


How It Works

  1. Create a native/ directory alongside your .bxs entry script.

  2. Write one or more .rs files inside native/.

  3. Each .rs file exports a register_bifs() and/or register_classes() function.

  4. Run matchbox --target native app.bxs.

MatchBox detects native/, compiles the Rust files together with the VM, merges all BIF and class registrations, and produces a single binary.


Macros

All interop macros are re-exported from the matchbox_vm crate — no separate matchbox_macros import is needed:

use matchbox_vm::{matchbox_fn, matchbox_class, matchbox_methods};

#[matchbox_fn] — Expose a Rust function as a BoxLang BIF

Annotate a plain Rust function with typed parameters. The macro generates a corresponding {name}_wrapper function that carries the low-level BIF signature expected by the VM (fn(&mut dyn BxVM, &[BxValue]) -> Result<BxValue, String>).

The wrapper handles argument-count validation and type coercion automatically.

Usage

BoxLang:

Supported Parameter Types

Rust parameter type
VM conversion applied by the macro

f64

args[i].as_number()

i32

args[i].as_int()

bool

args[i].as_bool()

String

vm.to_string(args[i])

BxValue

passed through unchanged

The return value is always wrapped as BxValue::new_number(result as f64). For BIFs that need to return other types (strings, null, objects), write a manual BIF instead (see Manual BIF Signature).

What the Macro Generates


#[matchbox_class] — Expose a Rust struct as a BoxLang native object

Annotate a struct to auto-implement the BxNativeObject trait. The generated implementation delegates get_property, set_property, and call_method to a dispatch_method function that is generated by #[matchbox_methods].

Always pair #[matchbox_class] with a #[matchbox_methods] impl block.

Usage

BoxLang (instantiate with new rust:<module>.<Class>(...)):


#[matchbox_methods] — Generate a method dispatcher for a native class

Annotate an impl block to generate a dispatch_method function that routes BoxLang method calls to the correct Rust method by name (case-insensitive).

#[matchbox_fn] type-coercion rules apply to each method's parameters.

Usage

BoxLang calls obj.process(42) and the dispatcher resolves it to MyStruct::process(&self, 42.0).

What the Macro Generates


#[matchbox_module] — Module marker (no-op)

A no-op attribute that serves as documentation: apply it to the top-level mod or impl to indicate the file is a Native Fusion module. Currently passes through unchanged.


Registration Entry Points

Every .rs file in native/ may export two entry-point functions. MatchBox calls them both at startup.

register_bifs() — standalone functions

BIF names must be unique across all files in native/.

register_classes() — native object constructors

BoxLang uses the key to resolve new rust:mymodule.MyClass(...).


Manual BIF Signature

When you need full control (e.g. returning a string, null, or an object pointer), skip #[matchbox_fn] and write the low-level signature directly:


Project Layout

Multiple files are supported as long as BIF and class names are unique across all files.


Using External Rust Crates

Add a Cargo.toml to the native/ directory to pull in dependencies:

MatchBox compiles this as a standard Cargo project and links the output into the final binary.


Limitations

Feature
Status

Native builds (--target native)

WASM builds (--target js / --target wasm)

❌ Not supported

Multiple .rs files in native/

External Rust crates via native/Cargo.toml

Return types other than f64 from #[matchbox_fn]

⚠️ Use manual BIF signature

Mutable self in #[matchbox_methods]

✅ Works — dispatcher takes &mut self

Property access on native objects (obj.field)

⚠️ Override get_property in BxNativeObject

See native-builds.md for the complete native build reference and differences-from-boxlang.md for the full list of features not available in MatchBox.

Last updated

Was this helpful?