# \[ANN\] jlrs 0.22: Julia version autodetection, async closure support, and more!

**URL:** <https://discourse.julialang.org/t/ann-jlrs-0-22-julia-version-autodetection-async-closure-support-and-more/133073>\
**Category:** Package Announcements\
**Tags:** package, interoperability, rust\
**Created:** [October 11, 2025, 3:49pm UTC](https://discourse.julialang.org/t/ann-jlrs-0-22-julia-version-autodetection-async-closure-support-and-more/133073 "2025-10-11T15:49:06Z")\
**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:** [October 11, 2025, 3:49pm UTC](https://discourse.julialang.org/t/ann-jlrs-0-22-julia-version-autodetection-async-closure-support-and-more/133073/1 "2025-10-11T15:49:06Z")

</div>

jlrs is a crate for the Rust programming language for interop between Rust and Julia, version 0.22 brings many changes. The tutorial has been updated to this new version.

### Version and juliaup support

Julia versions 1.10 up to and including 1.12 are supported. The MSRV is 1.85, the codebase has been migrated to the 2024 edition of Rust. Unlike previous versions the targeted Julia version is now detected at build time, all version features (e.g. `julia-1-10`) have been removed. The old `JULIA_DIR` environment variable has been renamed to `JLRS_JULIA_DIR`.

Using jlrs with juliaup has long been unsupported, but is now possible by installing `jlrs-launcher`. This application uses juliaup internally to find the requested Julia version; by invoking `jlrs-launcher +1.12 cargo run`, `cargo run` is executed in a new process where the environment has been updated to allow the version to be detected and the library to be linked.

The JlrsCore package is used internally by jlrs, the specific version that is used can be overridden with the environment variables `JLRS_CORE_REVISION`, `JLRS_CORE_REPO`, `JLRS_CORE_VERSION` and `JLRS_CORE_NO_INSTALL`.

### Async runtime

The async runtime has been updated to support, and in some cases require, async closures. Async closures that take an `AsyncGcFrame` implement the `AsyncTask`-trait. The `async_scope` method requires an async closure to be used instead of a closure that returns an async block. Unsafe work-arounds for lifetime limitations of closure that return async blocks, like `relaxed_async_scope`, have been removed.

Thanks to the stabilization of async methods in traits, traits with such methods no longer depend on `async_task`.

### Weak types and targets

Unrooted data has long been called a `Ref` in jlrs, but this is a misnomer: there is no additional level of indirection, rather it’s weakly instead of strongly referenced from Rust. Such data is now called `Weak`, types like `ValueRef` have been renamed to `WeakValue`. Similarly, unrooting targets have been renamed to weak targets.

### Exported type derive macros

The `OpaqueType` and `ForeignType` traits, which are used to export Rust types to Julia, are now derive macros. The `ParametricBase` and `ParametricVariant` traits have been removed; `OpaqueType` now supports types with generics. Features like setting the super-type of an exported type are now handled by annotating the struct instead of implementing a trait method. A custom mark function for a `ForeignType` can be implemented by annotating the fields that reference Julia data or by implementing the `Mark` trait.

### Scope generics

The previous version of jlrs moved the return type of a scope from the method to the trait. This was a bad choice and has been reverted. The unnameable generic type of the scope has been removed from the signature in favor of using `impl Trait`. The `Returning` and `LocalReturning` traits have been removed.

### Calling Julia functions

Methods that call a function with a small number of arguments like `Call::call1` have been deprecated in favor of `Call::call`. Providing keyword arguments with `ProvideArguments::provide_arguments` has been deprecated in favor `Call::call_kw`. The keyword arguments must be provided as a `NamedTuple`. The managed `Function` type has been removed and replaced by an abstract type.

### Other changes

The exception handler passed to `catch_exceptions` is now invoked inside the catch block. It takes an `Exception` instead of a `Value`.

Arrays can no longer be index with tuples like `(1, 2)`, use arrays: `[1, 2]` instead.

The `IntoJlrsResult` trait has been removed in favor of supporting the `?` operator.

The multithreaded runtime can no longer be started but must be spawned. They require the use of scoped threads to ensure that the main thread outlives all adopted threads.

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