Flutter Cross-Platform Fix: Solving the dart:html Error the Right Way
👨💻 Software Engineer | 💡 Kotlin Expert | 📱 Android Enthusiast
Previously SDE-III at DhiWise, I’m a Kotlin-focused developer passionate about building scalable, modern software-primarily on Android, but also exploring AI 🤖 and backend technologies. I use this space to share practical insights, clean code practices, and thoughts on the future of tech 🚀

If you’ve ever included some web-only code in your Flutter project, it might work perfectly in Chrome-until you try running it on your phone or building an APK.
Suddenly, Flutter throws errors like these:
Error: Dart library 'dart:html' is not available on this platform.
import 'dart:html' as html;
^
Error: Dart library 'dart:js_util' is not available on this platform.
import 'dart:js_util' as js_util;
Error: Dart library 'dart:js' is not available on this platform.
import 'dart:js' as js;
💥 Just like that, your mobile build is broken.
So what’s going on, and how do you fix it? Let’s break it down.
❌ Why This Happens
The root cause:
dart:html,dart:js, anddart:js_utilare web-only libraries.They simply don’t exist on mobile or desktop.
Why?
Mobile doesn’t have a DOM (no HTML elements).
Mobile doesn’t run JavaScript in a browser context.
Each platform uses its own APIs (Platform Channels, not Web APIs).
So when Flutter compiles for iOS/Android, it looks for those libraries… and can’t find them.
🛠 Two Proven Fixes (Pick One)
When you’re stuck between web and mobile, you have two safe routes forward:
Conditional imports with wrapper classes (zero dependencies, more control)
Use the
universal_htmlpackage (simpler, one-liner fix for most teams)
Let’s dive into both.
🔹 Approach 1: Conditional Imports (Maximum Control)
Best for teams that want zero external dependencies and full control of platform-specific code.
Step 1: Create Web implementation
// File: lib/utils/web_utils_web.dart
import 'dart:html' as html;
class WebUtils {
static String getBrowserInfo() => html.window.navigator.userAgent;
static String getCurrentUrl() => html.window.location.href;
static void saveToLocalStorage(String k, String v) => html.window.localStorage[k] = v;
static String? getFromLocalStorage(String k) => html.window.localStorage[k];
}
Step 2: Create Mobile fallback
// File: lib/utils/web_utils_mobile.dart
class WebUtils {
static String getBrowserInfo() => 'Not available on mobile';
static String getCurrentUrl() => 'Not available on mobile';
static void saveToLocalStorage(String k, String v) {}
static String? getFromLocalStorage(String k) => null;
}
Step 3: Add Conditional Export
// File: lib/utils/web_utils.dart
export 'web_utils_stub.dart'
if (dart.library.html) 'web_utils_web.dart'
if (dart.library.io) 'web_utils_mobile.dart';
// File: lib/utils/web_utils_stub.dart
class WebUtils {
static String getBrowserInfo() => 'Unsupported';
static String getCurrentUrl() => 'Unsupported';
static void saveToLocalStorage(String k, String v) {}
static String? getFromLocalStorage(String k) => null;
}
Step 4: Use it anywhere
import 'utils/web_utils.dart';
Text('Browser: ${WebUtils.getBrowserInfo()}')
✅ Done! Flutter automatically picks the correct file depending on platform.
🔹 Approach 2: universal_html (Simplest Fix)
If you don’t want extra boilerplate, just add one package:
Step 1: Add dependency
dependencies:
universal_html: ^2.2.4
Step 2: Replace imports
// Old ❌
import 'dart:html' as html;
import 'dart:js_util' as js_util;
import 'dart:js' as js;
// New ✅
import 'package:universal_html/html.dart' as html;
import 'package:universal_html/js_util.dart' as js_util;
import 'package:universal_html/js.dart' as js;
Step 3: Wrap in try/catch for safety
static String getBrowserInfo() {
try {
return html.window.navigator.userAgent;
} catch (_) {
return 'Not running on web';
}
}
Now the same code runs everywhere — no more crashes on mobile builds.
⚖️ Which One Should You Use?
Go with Conditional Imports if:
You want no dependencies
You need platform-optimized implementations
Your app has strict enterprise requirements
Go with Universal HTML if:
You want the fastest, easiest fix
You’re working on a standard Flutter app
You value simplicity over boilerplate
👉 For 90% of projects, universal_html is enough.
💡 Best Practices for Cross-Platform Flutter
Always test early on mobile + web
Don’t wait until release day.
flutter run -d chrome flutter run flutter build apkGuard your code with try/catch
Avoid crashes if the feature isn’t supported.Use
kIsWebfor quick checksimport 'package:flutter/foundation.dart'; if (kIsWeb) { ... }Document platform differences
Your future self (and teammates) will thank you.
🎯 Final Takeaway
dart:html works great… but only on web.
If you’re building cross-platform Flutter apps, you have two safe paths:
Conditional imports → More control, more setup
Universal HTML → Less effort, works out of the box
🚀 If you found this guide helpful, consider bookmarking it or dropping a reaction to support more in-depth tutorials.
🔔 Follow @themodularmindset to stay updated with the next articles.



