NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #3737 most downloaded on crates.io
a multi-language bindings generator for rust (codegen and cli tooling)
Last release 15 days ago
23 Sep 2026
Ships fairly regularly
a new release about every 2 months
Most releases are documented
notes for 9 of 11 stable releases
Nothing withdrawn
no release was ever pulled
1 years old
11 releases · first in 2025
One column per month.
Nothing published for this version
Kotlin: Fixed checksum failure on aarch64
chore: Release uniffi version 0.32.0
chore: Release uniffi version 0.32.0
--config flag now expects a global config file
rather than a flat uniffi.toml-style override. Old-style files will produce a warning and be ignored.
See #2866[ByRef] bytes UDL arguments now map to &[u8] on the Rust side instead of &Vec<u8>. UDL-defined functions whose Rust implementations take &Vec<u8> must change to &[u8]. Proc-macro signatures (fn foo(x: &[u8])) are unchanged. On the Kotlin side, call sites must now pass a direct java.nio.ByteBuffer rather than ByteArray; migrate with ByteBuffer.allocateDirect(arr.size).put(arr).flip(). Swift (Data) and Python (bytes) call sites are unchanged. (#2878)CrateConfigSupplier::from_cargo_metadata_command has changed.
It now inputs a MetadataCommand instance and a CargoMetadataOptions rather than just a no_deps flag.UniFfiTag from clippy::exhaustive_structs since downstream projects may depend on it #2809GlobalConfig struct for managing config. It replaces BindgenPathsLayer::get_config() method which has been removed. See #2866.[ByRef] bytes arguments now travel across the FFI as a ForeignBytes (pointer + length) value rather than a RustBuffer. External bindings need to accept the foreign-language byte buffer at the call site and lower it to ForeignBytes for the duration of the call (no copy). (#2878)Global config file support via --config. See the docs.
Traits can now be exported with #[uniffi::export(foreign)] for foreign-only implementations, or #[uniffi::export(rust, foreign)] for both Rust and foreign implementations. The with_foreign flag is deprecated in favor of rust, foreign.
Recursive enums are now supported. UniFFI automatically detects when enum and record types participate in cycles — self-referential, mutually recursive, or cycling through a record — and generates appropriate bindings: indirect in Swift, forward references in Python (#2834).
Box<T> now automatically implements FFI traits when T implements them, allowing direct use in enum variants and function parameters without NewType wrappers (#2808)
Record fields can now be renamed with the proc-macro name = "new_field_name" attribute (#2794)
Items can be excluded from the generated bindings using uniffi.toml.
Added mutable_records configuration option to allow specific records to remain mutable even when generate_immutable_records is enabled (Kotlin and Swift).
Kotlin objects now have an uniffiIsDestroyed property that returns true if the Rust reference no longer exists (#2825)
Updated askama version to 0.15.6
Custom Types can have docstrings in some languages (#2853)
Ruby: Expose standard Rust traits for generated ruby code (#2883)
Ruby: Add support for sync foreign traits (#2916)
Ruby: Add async support (#2923)
Added zero-copy transfer of &[u8] / [ByRef] bytes arguments from foreign code to Rust. Kotlin (java.nio.ByteBuffer, must be direct), Swift (Data), and Python (bytes-like, buffer protocol) pass byte buffers as pointer + length (ForeignBytes) rather than copying through RustBuffer. Not yet supported on Ruby, and not yet supported in async functions on any language (#2878).
#[uniffi::export(async_runtime = "tokio")] can now be applied to trait exports, wrapping each method's FFI scaffolding future in async_compat::Compat the same way it does for inherent impls and free functions (#2899).
Added support for using HashSet with proc-macros
Allow literal number suffix with derive(uniffi::Enum)(#2926)
Kotlin: Fixed JNA direct-mapped u8/u16 return values by widening the internal return carrier to Int, which avoids signedness mismatches during checksu
u8/u16 return values by widening the internal return carrier to Int, which avoids signedness mismatches during checksum validation and other direct-return paths on Android ARM32. (#2897)FfiConverterString silently stripping a leading U+FEFF byte order mark from Rust strings.Changelog update for 0.31.1
Changelog update for 0.31.1
chore: Release uniffi version 0.31.0
chore: Release uniffi version 0.31.0
uniffi-bindgen command no longer accepts the --lib-file argument. Instead, pass the
library directly without a UDL file.[Swift|Kotlin|Python|Ruby]BindingGenerator types. Use uniffi::generate instead
to generate these bindings.BindgenCrateConfigSupplier. Use the new BindgenPaths type instead.uniffi::generate function. This implements the uniffi-bindgen generate command and
allows it to be run programmatically.--library argument of uniffi-bindgen is deprecated and no longer has an effect.
uniffi-bindgen will now auto-detect when the source path is a library rather than a UDL file.BindgenPaths type, which is the new way to find UDL and TOML data.name = "NewVariantName" attribute (#2783)uniffi-bindgen that doesn't depend on cargo-metadata (#2746)toString(),
equals(), hashCode(), and compareTo() implementations. Flat enums only support exporting Display. (#2700).Eq, Cmp etc would generate invalid code if the Rust name had unusual captialization (#2707).#[doc(...)] attributes in exported blocks (#2777)__eq__ (#2741)0.30.x and the Rust code is built with
0.31.x, or vice-versa.module_path field now stores full module paths rather than crate names only.
External bindings authors will probably need to make some minor changes to work with this.
See https://github.com/mozilla/uniffi-rs/pull/2695/ for examples.chore: Release uniffi version 0.30.0
chore: Release uniffi version 0.30.0
#[uniffi::trait_interface] attribute.class PyTraitName(RustTraitName):name = "NewName" attribute (like already supported for methods and constructors) (#2661)Display, Hash, Eq etc) (#2555)Ord trait, allowing objects to be ordered by Rust (#2583).#[uniffi(default)] literals are now optional - eg, #[uniffi(default)] and #[uniffi(default = 0)] are equivalent.
Similarly for args; #[uniffi::export(default(arg_name))].
When no literal is specifed, named types (objects, records, etc) can be used as long as they have suitable default values.
(#2543).
Custom types too (#2603)enum and object types can be used as error type (#2658)uniffi_bindgen::backend has been removed.#[uniffi(default)] changes how defaults are represented.FfiType::RustArcPtr has been removed and the FFI type for objects/interfaces is now a u64.
Bindings authors will need to update their code to reflect this:
u64 valuesu64 handle rather than a raw pointeru64 handle rather than a raw pointerEnums and Records can have methods, so the Method now carries self_type instead of the object name.
In the templates, for Callable.takes_self() is replaced with Callable.self_type().free, clone, followed by a field for each interface method.
Note That free is now at the start of the vtable rather than the end.Nothing published for this version
Fixed a bug where objects with alignment >= 32 could be freed to early
chore: Release uniffi version 0.29.3
chore: Release uniffi version 0.29.3
Allow uniffi_reexport_scaffolding! macro to work in Rust 2024
Allow uniffi_reexport_scaffolding! macro to work in Rust 2024 (#2476)
Python: fix issues with unusual name capitalization, (#2464)
Swift bindings can now generate automatic conformance to the CaseIterable protocol for simple enums and errors using generate_case_iterable_conformance = true in the configuration.
Swift bindings can now generate automatic conformance to the Codable protocol for records, enums and errors using generate_codable_conformance = true in the configuration. Be aware that serialization in Swift may lead to different and incompatible results compared to serialization in Rust.
Some async-related names have changed. Bindings authors may need to update their code to reflect the new names. This is a name-change only -- the FFI and semantics are still the same.
UniffiForeignFutureFree is now UniffiForeignFutureDroppedCallbackUniffiForeignFuture is UniffiForeignFutureDroppedCallbackStruct.RustFuturePoll::MaybeReady is now RustFuturePoll::Wake.Your coding agent can read these notes before it upgrades. Set up the MCP server →