Flutter Web and Desktop
One Flutter codebase can run on phones, in the browser, and on Windows, macOS, and Linux desktops. Teams use this reach to share design and logic across every device their users own. The experience on each platform still needs care, because a mouse, a keyboard, and a wide window change how people interact with an app.
Platforms at a Glance
┌── Android
├── iOS
One Dart ─────┼── Web (Chrome, Safari, Edge, Firefox)
codebase ├── Windows
├── macOS
└── Linux
Turning On Platforms
Check which platforms are ready on your machine:
flutter devices
flutter config --enable-web
flutter config --enable-windows-desktop
flutter config --enable-macos-desktop
flutter config --enable-linux-desktop
Add a platform folder to an existing project:
flutter create --platforms=web,windows .
Desktop development requires the matching toolchain: Visual Studio with C++ tools for Windows, Xcode for macOS, and a few build packages for Linux.
Running and Building
| Goal | Command |
|---|---|
| Run in Chrome | flutter run -d chrome |
| Build the website files | flutter build web |
| Run on Windows | flutter run -d windows |
| Build a Windows app | flutter build windows |
| Build a macOS app | flutter build macos |
| Build a Linux app | flutter build linux |
The web build produces a folder named build/web. Upload its contents to any static host, such as Firebase Hosting, GitHub Pages, or a standard web server.
Checking the Platform in Code
import 'package:flutter/foundation.dart';
if (kIsWeb) {
print('Running in a browser');
} else if (defaultTargetPlatform == TargetPlatform.windows) {
print('Running on Windows');
}
The dart:io library, which offers Platform and File, does not work in the browser. Test kIsWeb before touching it, or use packages that support the web.
Differences That Matter
| Area | Mobile | Web and Desktop |
|---|---|---|
| Input | Touch | Mouse and keyboard |
| Window | Fixed screen size | Resizable window |
| Files | Sandboxed storage | File dialogs, local paths, downloads |
| Navigation | Back gesture | URLs, menus, shortcuts |
| Text | Taps and selection handles | Click, drag, copy and paste |
Adapting the Layout
A phone layout stretched across a 1920-pixel window looks sparse. Use breakpoints, as in the responsive layout topic, to switch from a bottom bar to a side navigation rail on wide screens, and to limit line length.
Phone Desktop window
┌───────────┐ ┌────┬─────────────────────────┐
│ content │ │nav │ content (max width) │
│ │ │rail│ │
├───────────┤ │ │ │
│ bottom nav│ └────┴─────────────────────────┘
└───────────┘
Mouse and Keyboard Support
Hover Effects
MouseRegion(
cursor: SystemMouseCursors.click,
onEnter: (_) => setState(() => hovering = true),
onExit: (_) => setState(() => hovering = false),
child: Container(color: hovering ? Colors.blue : Colors.grey),
)
Keyboard Shortcuts
Shortcuts(
shortcuts: {
LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyS): SaveIntent(),
},
child: Actions(
actions: {
SaveIntent: CallbackAction<SaveIntent>(onInvoke: (intent) => save()),
},
child: Focus(autofocus: true, child: MyEditor()),
),
)
Desktop users expect familiar shortcuts such as copy, paste, undo, and save. Scroll bars, right-click menus, and tab-key navigation add polish.
Web-Specific Concerns
- Load time: A Flutter web app downloads an engine and app code before it draws. Show a simple loading indicator in
web/index.html. - URLs: Use
go_routerso every screen has a shareable address and the browser back button works. - Search visibility: Flutter web renders to a canvas, which search engines read poorly. Apps suit dashboards and tools better than content sites that depend on organic search.
- Page title and icon: Edit
web/index.htmlandweb/manifest.jsonto match your brand. - Cross-origin requests: Browsers block calls to servers that lack the proper CORS headers.
Desktop-Specific Concerns
- Window size: Set a sensible minimum size so the layout never collapses. The
window_managerpackage controls size, position, and title. - Installers: Package the app for each system, such as MSIX for Windows or a DMG for macOS.
- Code signing: Windows and macOS warn users about unsigned apps, so signing builds trust.
- Native menus: Menu bars on macOS and Windows follow different conventions.
Package Support
Plugins differ in platform coverage. Check the "Platforms" tags on the package page before you commit. A camera plugin may support Android and iOS but not Windows. Pick alternatives or write platform-specific code behind a shared interface.
abstract class FileSaver {
Future<void> save(String name, List<int> bytes);
}
// MobileFileSaver, WebFileSaver, DesktopFileSaver each implement it
Practice Ideas
Run an existing app in Chrome and resize the window from narrow to wide. Add a side rail for wide screens and a bottom bar for narrow ones. Add one keyboard shortcut and one hover effect, then build the web version and open it from a local web server.
