NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #3666 most downloaded on crates.io
a multi-language bindings generator for rust (interal macro crate)
Last release 15 days ago
23 Sep 2026
Ships fairly regularly
a new release about every 2 months
Most releases are documented
notes for 12 of 14 stable releases
Nothing withdrawn
no release was ever pulled
2 years old
14 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.Bindings support lift and lower for CustomTypes in uniffi.toml to match the docs
Bindings support lift and lower for CustomTypes in uniffi.toml to match the docs (#2438)
Python: fix using Vecs and other composite types in tuple enums (#2445)
Kotlin: fix interfaces in sequences and records being not disposed (#2479)
Rust 2024 edition is supported, msrv is 1.82.0
The uniffi-bindgen CLI support no longer brings in the clap/color feature, reducing dependencies (#2435)
Protocols generated for Swift now conform to the Sendable protocol. This means that UniFFI traits will too, but
it also means foreign implemented traits also must when Swift 6 conformance is enabled.
See the Swift section of the manual for more. (#2450)
You can now optionally specify extra frameworks like CoreBluetooth or CoreFoundation when generating a modulemap file for an xcframework.
We've made a number of breaking changes to fix long standing paper-cuts with UniFFI in multi-crate and procmacro+udl environments.
We've made a number of breaking changes to fix long standing paper-cuts with UniFFI in multi-crate and procmacro+udl environments.
See the detailed upgrade notes
While no changes are required to foreign code, we apologize for the inconvenience!
You are impacted if you use UniffiCustomTypeConverter to implement "Custom types",
or use UDL with types from more than one crate.
UniffiCustomTypeConverter has been removed, you must now use the
custom_type! macro instead.
The UDL syntax for external types has changed.
typedef extern MyEnum; has been replaced
with typedef enum MyEnum;. [Custom] and [External] are the only supported attributes for a typedef.
"remote" types (where UDL can re-export a type defined in
a non-UniFFI crate - eg, log::Level) must now use a
[Remote] attribute.
Various use_udl_*/use_remote_type etc macros have been removed.
uniffi::generate_component_scaffolding has been removed. It's almost certainly unused as it is
behind the wrong feature and undocumented. uniffi::generate_scaffolding does exacly the same thing and is
correctly behind the build feature.Kotlin and Swift follow Python: Proc-macros exporting an impl Trait for Struct block now has a class inheritance
hierarcy to reflect that.
#2297, #2363
External types work much better, particularly between UDL and proc-macros. (Kotlin external errors do not work - #2392).
Swift interfaces are marked as Sendable (#2318)
Removed the log dependency and logging statements about FFI calls. These were not really useful
to consumers and could have high overhead when lots of FFI calls are made. Instead, the
ffi-trace feature can be used to get tracing-style printouts about the FFI.
External errors work for Swift and Python. Kotlin does not work - see #2392.
Added disable_java_cleaner option for kotlin to allow for Java 8 compatible code
Proc-macros now allow Enums to hold objects (#1372)
Swift and Kotlin make it possible to opt-out of the runtime checksum integrity tests done as the library is initialized. Opting out will shoot yourself in the foot if you mixup your build pipeline in any way, but might speed the initialization. (Python apparently hasn't made these checks for some time, so no changes there!)
Switching jinja template engine from askama to rinja.
For wasm32 build targets, Futures do not have to be Send (#2418),
making them compatible with wasm-bindgen Futures.
Added the FfiType::MutReference variant.
Callable trait has changed, return_type and throws_type are now references.
Type::External has been removed. Binding authors must now check the type is local themselves before
deciding to treat it as a local or external type.
To get a feel for the impact on the bindings, see where we first did this for custom types, and where we then stopped using it entirely
Fixed bug in metadata extraction with large ELF files.
Your coding agent can read these notes before it upgrades. Set up the MCP server →