Describe the bug
The uniffi dependency in livekit-uniffi/Cargo.toml (livekit/rust-sdks) unconditionally enables the "cli" feature under [dependencies]. This causes uniffi_bindgen — a build-time code generator — and all its transitive dependencies (reqwest, hyper, ring, clap, serde_json, askama) to be compiled into liblivekit_uniffi.a inside RustLiveKitUniFFI.xcframework.
~11.5 MB of build-tool object code ends up in the static library (26% of the 45 MB .a). These are tools for generating Swift/Kotlin/Python/Ruby bindings from Rust UDL — they have no runtime purpose.
Current Cargo.toml:
[dependencies]
uniffi = { version = "0.30.0", features = ["cli", "scaffolding-ffi-buffer-fns"] }
Because "cli" is unconditional, Cargo's feature unification compiles uniffi_bindgen and its full dependency tree into the static library — even when only the [lib] target is built. UniFFI's own docs recommend running the bindgen binary with --features=uniffi/cli (ref), implying cli should be opt-in — but the current Cargo.toml enables it unconditionally. UniFFI #1482 documents the same underlying issue.
A possible fix is to gate "cli" behind an optional feature with required-features on the [[bin]] target — this is exactly how UniFFI's own Cargo.toml is structured upstream:
[features]
bindgen = ["uniffi/cli"]
[dependencies]
uniffi = { version = "0.30.0", features = ["scaffolding-ffi-buffer-fns"] }
[[bin]]
name = "uniffi-bindgen"
path = "bindgen.rs"
required-features = ["bindgen"]
This way cargo build --lib skips the binary and excludes all CLI dependencies from the static library. The bindgen binary remains available via cargo run --features bindgen --bin uniffi-bindgen.
Introduced in v2.11.0 via PR #822. All versions from v2.11.0 onwards (including v2.12.1) are affected. Root cause is in livekit/rust-sdks — livekit-uniffi/Cargo.toml.
SDK Version
livekit/client-sdk-swift v2.12.1 (latest)
livekit/livekit-uniffi-xcframework v0.0.5
- Affected since v2.11.0
iOS/macOS Version
All — build-time packaging issue, not OS-specific.
Xcode Version
Xcode 26.2 / Swift 6.2.3. Issue is Xcode-independent (originates in the Rust Cargo build).
Steps to Reproduce
-
Download RustLiveKitUniFFI.xcframework from the v0.0.5 release:
curl -L -O "https://github.com/livekit/livekit-uniffi-xcframework/releases/download/0.0.5/RustLiveKitUniFFI.xcframework.zip"
unzip RustLiveKitUniFFI.xcframework.zip
-
Check the static library size:
BINARY="RustLiveKitUniFFI.xcframework/ios-arm64/liblivekit_uniffi.a"
ls -lh "$BINARY" # → 45 MB
-
Count build-tool symbols that should not be present:
nm "$BINARY" | grep -c "uniffi_bindgen" # → 5,163
nm "$BINARY" | grep -c "reqwest" # → 566
nm "$BINARY" | grep -c "clap" # → 1,041
-
Measure build-tool object file bloat:
mkdir objfiles && cd objfiles && ar x "../$BINARY"
ls -l *.o | grep -iE "(uniffi_bindgen|uniffi_pipeline|reqwest|hyper|ring-|askama|serde_json|clap)" \
| awk '{sum+=$5} END {printf "%.1f MB\n", sum/1048576}'
# → 11.5 MB
Expected behavior
The static library should contain only runtime code (livekit_protocol, tokio, jsonwebtoken, prost). Build-time code generators and their dependencies should not be shipped. Gating the "cli" feature should reduce the .a by ~11.5 MB.
Screenshots
N/A — binary analysis issue.
Logs
Sample nm output — note Python and Ruby code generators inside the iOS binary:
__ZN...uniffi_bindgen..bindings..python..pipeline..nodes..Field...
__ZN...uniffi_bindgen..bindings..ruby..gen_ruby..Config...
__ZN...uniffi_bindgen..bindings..swift..gen_swift..Config...
Of the 35,701 executable text symbols, 8,948 (25.1%) come from build-tool dependencies.
Full bloat breakdown (click to expand)
| Crate |
Symbols |
Object size |
Purpose |
uniffi_bindgen |
5,163 |
7.9 MB |
Multi-language code generator |
uniffi_pipeline |
3,474 |
0.1 MB |
Binding AST pipeline |
ring |
2,740 |
0.5 MB |
TLS crypto (bindgen dependency) |
serde_json |
1,278 |
0.2 MB |
JSON parsing (bindgen dependency) |
hyper |
1,170 |
0.6 MB |
HTTP implementation (bindgen dep) |
clap |
1,041 |
0.9 MB |
CLI argument parser (bindgen dep) |
reqwest |
566 |
1.3 MB |
HTTP client (bindgen dependency) |
askama |
146 |
~0 MB |
Template engine (bindgen dependency) |
| Total |
~15,578 |
11.5 MB |
None of these are runtime deps |
Legitimate runtime dependencies (expected, should remain):
| Component |
Symbols |
Purpose |
| livekit_protocol |
2,625 |
Signaling protocol |
| tokio |
2,286 |
Async runtime |
| jsonwebtoken |
283 |
Access token validation |
| prost |
211 |
Protobuf serialization |
| livekit_api |
175 |
API types |
Discovered during binary analysis while integrating LiveKit v2.12.1 into an iOS monorepo. Happy to provide additional data or test a fixed build.
Describe the bug
The
uniffidependency inlivekit-uniffi/Cargo.toml(livekit/rust-sdks) unconditionally enables the"cli"feature under[dependencies]. This causesuniffi_bindgen— a build-time code generator — and all its transitive dependencies (reqwest, hyper, ring, clap, serde_json, askama) to be compiled intoliblivekit_uniffi.ainsideRustLiveKitUniFFI.xcframework.~11.5 MB of build-tool object code ends up in the static library (26% of the 45 MB
.a). These are tools for generating Swift/Kotlin/Python/Ruby bindings from Rust UDL — they have no runtime purpose.Current Cargo.toml:
Because
"cli"is unconditional, Cargo's feature unification compilesuniffi_bindgenand its full dependency tree into the static library — even when only the[lib]target is built. UniFFI's own docs recommend running the bindgen binary with--features=uniffi/cli(ref), implyingclishould be opt-in — but the current Cargo.toml enables it unconditionally. UniFFI #1482 documents the same underlying issue.A possible fix is to gate
"cli"behind an optional feature withrequired-featureson the[[bin]]target — this is exactly how UniFFI's own Cargo.toml is structured upstream:This way
cargo build --libskips the binary and excludes all CLI dependencies from the static library. The bindgen binary remains available viacargo run --features bindgen --bin uniffi-bindgen.Introduced in v2.11.0 via PR #822. All versions from v2.11.0 onwards (including v2.12.1) are affected. Root cause is in
livekit/rust-sdks—livekit-uniffi/Cargo.toml.SDK Version
livekit/client-sdk-swiftv2.12.1 (latest)livekit/livekit-uniffi-xcframeworkv0.0.5iOS/macOS Version
All — build-time packaging issue, not OS-specific.
Xcode Version
Xcode 26.2 / Swift 6.2.3. Issue is Xcode-independent (originates in the Rust Cargo build).
Steps to Reproduce
Download
RustLiveKitUniFFI.xcframeworkfrom the v0.0.5 release:curl -L -O "https://github.com/livekit/livekit-uniffi-xcframework/releases/download/0.0.5/RustLiveKitUniFFI.xcframework.zip" unzip RustLiveKitUniFFI.xcframework.zipCheck the static library size:
Count build-tool symbols that should not be present:
Measure build-tool object file bloat:
Expected behavior
The static library should contain only runtime code (livekit_protocol, tokio, jsonwebtoken, prost). Build-time code generators and their dependencies should not be shipped. Gating the
"cli"feature should reduce the.aby ~11.5 MB.Screenshots
N/A — binary analysis issue.
Logs
Sample
nmoutput — note Python and Ruby code generators inside the iOS binary:Of the 35,701 executable text symbols, 8,948 (25.1%) come from build-tool dependencies.
Full bloat breakdown (click to expand)
uniffi_bindgenuniffi_pipelineringserde_jsonhyperclapreqwestaskamaLegitimate runtime dependencies (expected, should remain):
Discovered during binary analysis while integrating LiveKit v2.12.1 into an iOS monorepo. Happy to provide additional data or test a fixed build.