# \[ANN\] jlrs 0.23

**URL:** <https://discourse.julialang.org/t/ann-jlrs-0-23/136963>\
**Category:** Package Announcements\
**Tags:** package, announcement, interoperability, rust\
**Created:** [May 2, 2026, 6:35pm UTC](https://discourse.julialang.org/t/ann-jlrs-0-23/136963 "2026-05-02T18:35:04Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Taaitaaiger](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/taaitaaiger/32/49792_2.png) [@Taaitaaiger](https://discourse.julialang.org/u/Taaitaaiger)\
**Post date:** [May 2, 2026, 6:35pm UTC](https://discourse.julialang.org/t/ann-jlrs-0-23/136963/1 "2026-05-02T18:35:05Z")

</div>

jlrs is a crate for the Rust programming language that can be used to embed Julia in Rust applications and to write interop libraries to Rust crates that can be used by Julia. Version 0.23 supports Julia 1.10 up to and including 1.13, but 1.13 support should be considered experimental until this version has been officially released. The tutorial has been updated to this new version.

Version 0.23 brings several improvements, some of these changes are accompanied by changes in JlrsCore.jl. Version 0.7.0 of this package is available and is required to use jlrs v0.23.

# Tracked data

For a long time, jlrs has supported (mutably) tracking data to help avoid breaking aliasing rules in Rust. The immutable variant, `Tracked`, can now be cloned to create an additional tracked handle. Note that this may break existing code, cloning a tracked handle previously cloned the referenced data. To restore the old behavior, replace `foo.clone()` with `(&*foo).clone()`. (Thanks @Chrysoberyl!)

# Binding verification

jlrs works by using Julia’s C API, the list of used items is maintained manually for several boring reasons. This list wasn’t checked for compatibility with their signatures as defined by the C API. A new internal tool has been added that verifies compatibility; all issues detected with this tool have been resolved.

# Reflection and `julia_module`

When Rust bindings for Julia types are generated with JlrsCore.Reflect, they reference the path to the type that the bindings were derived from. At run-time, this path had to strictly match the path at reflection-time. These rules have been relaxed slightly: the `Main` module in this path can now be elided, and bindings generated with JlrsCore do so by default.

The `julia_module` macro is used with JlrsCore.Wrap to export types, functions, and constants defined in Rust to Julia. Its internals were a complete mess, they have been rewritten to follow a more typical (and more importantly: better testable) “parse → analyze → lower → codegen” pipeline. Thanks to this rewrite, more errors are now caught at compile time.

The syntax of `julia_module` itself has been left mostly unchanged, the only requirement that didn’t exist previously is that the `become`-statement must now come before any exported item. Exported items can now be marked with `pub`, `pub` items are automatically exported by the generated Julia module.

`julia_module` is no longer just tested with a script, a package test has been added to test that precompilation, reflection and doctests work. All issues detected with the package test have been resolved.

# Raw instantiation deprecation

Finally, the method `DataType::instantiate_unchecked`, which can be used to instantiate a new instance of a type, has been deprecated and will likely be removed in jlrs 0.24. Call one of the type’s constructors instead.

[GitHub](https://github.com/Taaitaaiger/jlrs)  
[Docs](https://docs.rs/jlrs/0.23.0/jlrs/)  
[Tutorial](https://taaitaaiger.github.io/jlrs-tutorial/)
