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

GoalCommand
Run in Chromeflutter run -d chrome
Build the website filesflutter build web
Run on Windowsflutter run -d windows
Build a Windows appflutter build windows
Build a macOS appflutter build macos
Build a Linux appflutter 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

AreaMobileWeb and Desktop
InputTouchMouse and keyboard
WindowFixed screen sizeResizable window
FilesSandboxed storageFile dialogs, local paths, downloads
NavigationBack gestureURLs, menus, shortcuts
TextTaps and selection handlesClick, 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_router so 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.html and web/manifest.json to 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_manager package 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.