Files
sovereign_browser_rust/plans/webkit-assessment.md
T

4.4 KiB

WebKitGTK Rust Binding Assessment

Current Situation

The C project (sovereign_browser) uses WebKitGTK 4.1 (webkit2gtk-4.1), which is the GTK3-based WebKit2 API. This is specified in the Makefile:

CFLAGS  += $(shell pkg-config --cflags webkit2gtk-4.1 libsoup-3.0 ...)

The Rust port currently uses the webkit2gtk crate v2.0.2, which is the Tauri fork of the gtk-rs WebKitGTK bindings. This crate wraps WebKitGTK 2.x (the GTK3 API), NOT WebKitGTK 4.1.

The Version Confusion

WebKitGTK has two independent versioning schemes:

pkg-config name GTK version WebKit API version Soup version Status
webkit2gtk-4.0 GTK3 WebKit2 libsoup2 Legacy
webkit2gtk-4.1 GTK3 WebKit2 libsoup3 Current stable (GTK3)
webkit6gtk GTK4 WebKitWebProcess libsoup3 Future (GTK4)

The C project uses webkit2gtk-4.1 — the GTK3 + libsoup3 variant. This is the current stable API for GTK3-based browsers.

Available Rust Crates

1. webkit2gtk v2.0.2 (current — Tauri fork)

  • Wraps: WebKitGTK 2.x (GTK3, libsoup2)
  • GTK version: GTK3 (gtk 0.18)
  • Soup version: libsoup3 (soup3 crate)
  • Status: Maintained by Tauri team, stable
  • API mismatch: Wraps an older WebKitGTK API than the C project uses
  • Feature flags: v2_2 through v2_40 control which API versions are available

2. tauri-webkit2gtk v0.14.0

  • Wraps: Same as above, different package name
  • Status: Tauri's own fork, same underlying bindings
  • Not useful: Same API as webkit2gtk 2.0

3. webkit2gtk-webextension v0.16.0

  • Wraps: WebKit web extension API only
  • Not useful: For browser extensions, not the main browser

4. GTK4 + webkit6gtk (does not exist yet as a Rust crate)

  • Wraps: WebKitGTK for GTK4
  • Status: No stable Rust crate exists
  • Not viable: Would require GTK4 migration and no bindings available

Assessment

The webkit2gtk 2.0 crate IS the right choice

Despite the version number confusion, the webkit2gtk 2.0.2 crate is the correct and only viable option for a Rust WebKitGTK browser:

  1. It's the only maintained Rust binding for WebKitGTK on GTK3
  2. It uses GTK3 (gtk 0.18), matching the C project's GTK3 dependency
  3. It uses libsoup3 (soup3 crate), matching the C project's libsoup-3.0 dependency
  4. The feature flags (v2_40) enable the latest WebKitGTK API features
  5. The API differences from the C project are minor — method names and signatures differ slightly but the functionality is the same

Why not switch to GTK4?

  • No stable Rust WebKitGTK binding exists for GTK4
  • GTK4 has a completely different widget API (no GtkNotebook, no GtkToolbar, etc.)
  • Would require a complete UI rewrite
  • The C project is GTK3, so staying on GTK3 maintains parity

The compilation errors are NOT a version problem

The ~25 remaining compilation errors are normal Rust binding API differences, not version incompatibilities:

Error Cause Fix
no method set_allow_popups Method doesn't exist in this binding Remove the call
no method read_to_end Needs InputStreamExtManual trait Add use gio::prelude::InputStreamExtManual
static mut Send/Sync Raw pointers aren't Send/Sync Use Mutex<Option<...>> instead of static mut
Notebook methods not found Need gtk::prelude::* Add the prelude import
RelayPool::query_sync return type Type inference failure Add explicit type annotation
UserScript::new args Takes 5 args not 3 Already fixed — pass &[] for allow/block lists
WebView::web_context Builder method not setter Already fixed — use builder pattern

Recommendation

Stay with webkit2gtk 2.0.2. It is the correct choice. The compilation errors are straightforward Rust API fixes, not architectural problems. Switching to a different WebKitGTK version would not help — there is no better Rust binding available.

Next Steps

  1. Fix the remaining ~25 compilation errors (all are minor API differences)
  2. Build and run the browser
  3. Test the Nostr bridge, login dialog, and tab management

The errors can be fixed by:

  • Adding use gtk::prelude::* where needed
  • Replacing static mut with Mutex<Option<...>>
  • Removing non-existent method calls (set_allow_popups)
  • Adding explicit type annotations where inference fails
  • Using the correct trait imports (InputStreamExtManual)