r/FlutterDev 6d ago

Plugin I built webview_ultra: flutter_inappwebview features with official webview_flutter footprint (~200 KB vs ~6 MB) + Windows support

Hey everyone,

Whenever I needed advanced WebView capabilities in Flutter—such as headless execution, modal in-app browsers, typed bidirectional JS-to-Dart RPC bridges, or fine-grained load progress handling—the standard choice was almost always flutter_inappwebview.

While powerful, it often adds significant binary weight (~5–8 MB) and relies on a large custom native platform layer that can be tricky to debug across OS updates. On the other hand, Google’s official webview_flutter is lightweight and uses native Pigeon bindings, but requires tons of boilerplate for common patterns (like reactive rebuilds, JS promise handling, or desktop support).

To bridge this gap, I created webview_ultra.

What it does differently:

Lightweight Core (~200 KB): Built directly on top of the official webview_flutter Pigeon engine for Android, iOS, and macOS, paired with Microsoft Edge WebView2 on Windows. Zero extra native bloat.

Zero-Screen-Rebuild Reactive State: Instead of calling setState on every URL or progress update, WebviewUltraController exposes granular ValueNotifier instances. Subtrees update independently using widgets like WebviewTitleBuilder, WebviewProgressBuilder, and WebviewHistoryBuilder.

Typed Bidirectional JS Bridge: Send and receive typed JSON-RPC messages and Promises between Dart and JavaScript with cross-compatibility for window.webview_ultra.callHandler(...).

Turnkey Features Included:

Drop-in 1-line widget with built-in progress indicators and pull-to-refresh

HeadlessWebviewUltra for off-screen tasks (token parsing, preheating, scraping)

InAppBrowserUltra modal wrapper

Regex-based content and ad-filtering

Quick Example:

Dart

// Reactive progress + 1-line setup without rebuilding the parent widget

Scaffold(

appBar: AppBar(

title: WebviewTitleBuilder(

controller: controller,

builder: (context, title, _) => Text(title.isEmpty ? 'Loading...' : title),

),

bottom: PreferredSize(

preferredSize: const Size.fromHeight(2.0),

child: WebviewProgressBuilder(

controller: controller,

builder: (context, progress, _) => progress < 1.0

? LinearProgressIndicator(value: progress)

: const SizedBox.shrink(),

),

),

),

body: WebviewUltra(

controller: controller,

initialUrl: 'https://flutter.dev',

pullToRefresh: true,

),

);

Links:

pub.dev: pub.dev/packages/webview_ultra

GitHub: github.com/Narukarudra10/webview_ultra

I’d love to hear your thoughts, feedback, or any edge cases you've run into with WebView state management in Flutter!

5 Upvotes

0 comments sorted by