Android Dark Mode Fix in Tauri: A Debugging War Story
Apr 8, 2026 · 6 min read
For weeks, the native Android status bar and navigation bar refused to update when toggling dark mode in a Tauri app. The JS code called the right function. The Rust handler logged the invocation. But the bars stayed stubbornly light.
Here's how I finally fixed it.
The Broken Bridge
The intended flow was clean: JavaScript calls invoke('plugin:theme|set_theme', { isDark }), which routes through Rust's Tauri plugin system, which calls into Kotlin to update the system bars.
Except the Kotlin ThemePlugin was never reached. Zero logcat output. Zero effect. The Rust-side plugin simply didn't exist — there was no handler registered to bridge the call to Android.
The Fix: Skip Rust Entirely
Instead of fixing the plugin chain, I bypassed the Rust layer entirely. Using a @JavascriptInterface annotated class injected directly into the WebView via onWebViewCreate():
Then in the Android setup:
Now JavaScript calls window.ThemeBridge.setTheme(isDark) directly — no Rust intermediary, no plugin chain, no silent failures.
The Lesson
Three weeks of debugging a broken abstraction. The fix was removing an unnecessary layer. It's a reminder that sometimes the most robust solution isn't fixing the bridge — it's asking whether the bridge should exist at all.