# `matrix_client`: the `native` feature does not do what it says - **Date:** 2026-08-18 - **Status:** raised, not fixed. This is not my crate and nothing currently depends on the broken combination; fixing it blind risks changing behaviour someone is relying on. - **Found while:** measuring what `makepad-table` would cost if it depended on `nigig-uikit` for camera and location. ## The defect `crates/matrix_client/Cargo.toml` declares a feature that gates three heavy dependencies: ```toml [features] default = ["native"] native = ["dep:tokio", "dep:reqwest", "dep:rusqlite"] ``` The source does **not** gate on that feature. It gates on the target: ```rust // crates/matrix_client/src/lib.rs #[cfg(not(target_arch = "wasm32"))] pub mod auth; #[cfg(not(target_arch = "wasm32"))] pub mod client; // ... and so on for http, persistence, sync_service, worker ``` Two different switches for the same set of modules. On a native target with the feature turned off, the modules still compile but their dependencies are absent: ``` cargo check -p matrix_client --no-default-features -> 19 errors: unresolved import `reqwest`, cannot find `tokio`, unresolved import `rusqlite` ``` 26 ungated uses across 7 files: | File | Uses | |---|---| | `worker.rs` | 9 | | `error.rs` | 4 | | `persistence.rs` | 4 | | `sync_service.rs` | 4 | | `client.rs` | 2 | | `http.rs` | 2 | | `types.rs` | 1 | ## What is *not* broken The wasm path is coherent: ``` cargo check -p matrix_client --no-default-features --target wasm32-unknown-unknown -> 0 errors ``` `target_arch = "wasm32"` and the absent dependencies agree there, because on wasm the `[target.'cfg(not(target_arch = "wasm32"))'.dependencies]` section is skipped anyway. The only broken combination is **native target with the feature off**, which nothing in this repo builds and no CI job covers — which is why it rotted without anyone noticing. ## Correcting an overstatement I previously said fixing this would "unblock wasm". That was wrong, and I should have checked before saying it. `nigig-core` has 8 wasm errors of its own that have nothing to do with `matrix_client`: ``` cargo check -p nigig-core --no-default-features --target wasm32-unknown-unknown -> 8 errors: cannot find function `spawn` in module `crate::platform` ``` Fixing `matrix_client` moves nobody closer to a wasm build on its own. ## Why it was not fixed here It buys the thing that surfaced it precisely nothing. `makepad-table` wanted `nigig-uikit` for its camera and location widgets, and `camera_widget` imports exactly two items from `nigig-core`: ```rust use nigig_core::syncing::{send_geocode_request, request_map_tile, ...}; ``` Both call `spawn_async`, which *is* the shared Tokio runtime, and `send_geocode_request` makes an HTTPS call to Nominatim. So the camera widget requires `nigig-core/native` by its own nature. `matrix_client` sits on the same flag: making it honour the feature would let *it* build without tokio, but `nigig-uikit` turns tokio straight back on through `nigig-core`. Net saving for that use case: zero. Measured, so the numbers are not guesses: | Configuration | Crates in the tree | |---|---| | `makepad-widgets` alone | 88 | | `+ nigig-uikit` | 274 | | `matrix_client` with `native` | 199 | | `matrix_client` without `native` (if it compiled) | 140 | ## Two ways to fix it **A. Make the source honour the feature.** Change 26 sites from `#[cfg(not(target_arch = "wasm32"))]` to `#[cfg(feature = "native")]`, and move the dependencies out of the target section into the plain one, where `optional = true` is what decides. This is the honest reading of what the feature claims. It is also the version that could change behaviour for a native build that somehow relied on the modules existing without the dependencies — none exists today, but the check is a compile, not a test. **B. Delete the feature.** If `matrix_client` is native-only in practice — and the 26 sites say it is — then `native` is a claim the crate does not honour, and removing it is more truthful than a flag nobody can use. The dependencies stay non-optional in the target section, where the wasm split already works. B is smaller and matches observed reality. A is right if a wasm or dependency-light build is actually wanted, in which case `nigig-core`'s 8 errors need fixing too, and that is the larger piece. ## Whichever is chosen, it needs a gate There is no CI job for `matrix_client`. A feature that nothing builds is a feature that breaks silently, which is exactly what happened. One line in a workflow: ```yaml - name: The native feature means what it says run: cargo check -p matrix_client --no-default-features ``` That step fails today. It should be added with the fix, not before it.