Flutter plugins with Apple Watch (watchOS) support, maintained by the flutterwatch.dev organization.
These are companions to flutter-watchos
— the Flutter watchOS custom embedder. Most are federated *_watchos
implementations of popular pub.dev plugins, produced with the
flutter-watchos plugin port tool and finished/verified by hand.
Publishing to pub.dev under the
flutterwatch.devpublisher is in progress. Each version badge below lights up automatically once its package is published; until then, add the package as a git dependency (see Usage).
watchOS plugins ship native code via dart:ffi: the package exports C
symbols from watchos/Classes/*.m, declares them under
flutter.plugin.platforms.watchos.ffiSymbols, and the flutter-watchos
CLI statically links them into the watch binary where Dart resolves them
with DynamicLibrary.process(). A plugin can additionally ship native
SwiftUI platform views (watchos/Views/*.swift) that the CLI compiles
into the app and the plugin embeds with WatchPlatformView
(package:flutter_watchos) — see video_player_watchos. Method-channel
plugins are not supported on watchOS — a package whose watchos: block
declares only pluginClass: will build but its channel calls throw
MissingPluginException (the CLI warns about this at build time).
One package here is not a port of an upstream plugin, because there is no upstream to port: WatchConnectivity is the only transport Apple provides between a watch and its phone, and it needs an implementation on both sides.
| Plugin | What it is | Backend |
|---|---|---|
flutter_watch_link |
First-party. One Dart API for phone↔watch messaging, application context, and guaranteed transfers — the same code on both devices. | WCSession (one FFI implementation, compiled for both) |
Upstream watch_connectivity is
phone-side only, and its "platform interface" is explicitly not a federated one
— there is no instance hook to implement — so a *_watchos implementation of
it is not possible. It also has no transferUserInfo, which is the tier a
companion app needs when the counterpart is asleep.
See its example/ for a worked
companion app — one main.dart, running on both devices.
Every plugin below has a working watchOS implementation, verified on the
watch simulator. Full details (API coverage, watchOS capability, and
porting notes) are in each package's README.md and PORTING_REPORT.md.
| Plugin | Upstream | watchOS backend |
|---|---|---|
path_provider_watchos |
path_provider |
NSSearchPathForDirectoriesInDomains |
shared_preferences_watchos |
shared_preferences |
NSUserDefaults |
package_info_plus_watchos |
package_info_plus |
NSBundle |
device_info_plus_watchos |
device_info_plus |
WKInterfaceDevice |
url_launcher_watchos |
url_launcher |
ASWebAuthenticationSession (web pages on the watch), WKApplication.openSystemURL (tel:/sms:), NSUserActivity Handoff (web, externalApplication) |
battery_plus_watchos |
battery_plus |
WKInterfaceDevice battery |
connectivity_plus_watchos |
connectivity_plus |
nw_path_monitor |
flutter_secure_storage_watchos |
flutter_secure_storage |
Keychain (SecItem*) |
network_info_plus_watchos |
network_info_plus |
getifaddrs (IP; no SSID) |
sensors_plus_watchos |
sensors_plus |
CoreMotion (CMMotionManager) |
local_auth_watchos |
local_auth |
LocalAuthentication (passcode) |
geolocator_watchos |
geolocator |
CoreLocation (CLLocationManager) |
video_player_watchos |
video_player |
AVFoundation + AVKit platform view |
audioplayers_watchos |
audioplayers |
AVFoundation (AVPlayer) |
in_app_purchase_watchos |
in_app_purchase |
StoreKit (SKProductsRequest, SKPaymentQueue) |
games_services_watchos |
games_services |
GameKit (GKLeaderboard, GKLocalPlayer) — leaderboards only † |
firebase_core_watchos |
firebase_core |
Firebase Apple SDK (FirebaseCore) |
firebase_auth_watchos |
firebase_auth |
Firebase Apple SDK (FirebaseAuth) |
firebase_storage_watchos |
firebase_storage |
Firebase Apple SDK (FirebaseStorage) |
firebase_messaging_watchos |
firebase_messaging |
Firebase Apple SDK (FirebaseMessaging) |
† games_services_watchos is staged at 0.0.1. Sign-in and score
submission have been observed working on a physical Apple Watch;
reading leaderboard entries has not — GKLocalPlayer reports an
authenticated player with an unresolved alias and GameKit then refuses
the read. The app under test was side-loaded rather than installed
through its companion, which is the leading suspect. See its
PORTING_REPORT.md.
First-party watch capabilities (platform detection, device info, haptics,
Digital Crown) ship in
flutter_watchos
itself — check there before adding a plugin.
These upstream plugins' core capability does not exist on watchOS, so a published package would be misleading:
| Plugin | Why not on watchOS |
|---|---|
webview_flutter |
No WebKit in the watchOS SDK, so no embeddable web view; a page can only be shown as a full-screen system sheet, which url_launcher_watchos does |
google_sign_in |
No GoogleSignIn watchOS SDK; sign-in is delegated to the paired iPhone |
image_picker |
No camera and no photo-picker UI on the watch |
google_maps_flutter |
No Google Maps SDK for watchOS (an Apple MapKit backend would not honestly implement the interface) |
Note the difference from tvOS: CoreLocation, HealthKit, CoreMotion, StoreKit purchasing, and (watchOS 9+) LocalAuthentication all exist on the watch — plugins built on those are portable, not excluded.
These have a watchOS-viable native backend and are good future additions;
they are simply out of scope for now (large surface or partial support):
sqflite (SQLite), flutter_tts (AVFoundation),
wakelock_plus (only a session-typed WKExtendedRuntimeSession, not a
general idle-timer disable), and cloud_firestore (the Firebase Apple SDK
ships Firestore's core as a prebuilt binary with no watchOS slice, so a
port needs Firebase's from-source Firestore build; the rest of the
network-viable Firebase family — core, auth, storage, messaging — is
ported above).
The upstream plugins do not endorse a watchOS implementation, so add
the *_watchos package to your app explicitly, alongside the upstream
plugin:
dependencies:
path_provider: ^2.1.0
path_provider_watchos: ^0.0.1The version badges in the table above are the current published versions —
use those, since these packages are still pre-1.0 and a caret constraint on
0.x is narrower than you may expect.
Then use the upstream plugin's API exactly as on iOS — the *_watchos
implementation registers automatically via Flutter's federated plugin
runner, with no imports or client code changes.
flutter_watch_link is the exception: it is not on pub.dev yet, so
depend on it via git.
dependencies:
flutter_watch_link:
git:
url: https://github.com/flutterwatch/plugins.git
path: packages/flutter_watch_linkA few packages need a writable directory and therefore also
path_provider_watchos: e.g. video_player_watchos (for
VideoPlayerController.file). Their READMEs note this.
Each package ships the upstream plugin's own example (its demo lib/ and
its official integration_test/) ported verbatim by flutter-watchos plugin port --include-example with a watchOS runner on top, plus a host-side unit
test. The examples and tests are unmodified — the example imports only the
app-facing plugin, and the *_watchos implementation registers federatedly
with no client code changes. Each is verified on the watch simulator:
cd packages/<plugin>_watchos/example
flutter-watchos drive \
--driver=test_driver/integration_test.dart \
--target=integration_test/<test-file> -d <watch-sim>The official integration tests pass on the watch for path_provider,
network_info_plus, sensors_plus, local_auth, device_info_plus, battery_plus,
connectivity_plus, shared_preferences (64/64), in_app_purchase, and
package_info_plus's plugin-level fromPlatform case — some cases self-skip on non-Android, as
upstream intends. Two upstream tests are written as phone-UI sweeps that
pump the demo's scrolling list and find widgets that a ~200 px watch screen
never materialises: package_info_plus's example test and
flutter_secure_storage's page-object app_test. Those fail on the watch for
viewport reasons, not plugin defects — the FFI implementations are proven by
the plugin-level cases, the host unit tests, and the unified demo. geolocator's
upstream example has no integration_test/ (its Baseflow demo is manual),
so that package is verified by building and running the example on the sim.
in_app_purchase_watchos additionally ships a purchase_test covering the full
StoreKit round trip (buy → purchaseStream → completePurchase); it needs
StoreKit testing, which only an Xcode launch activates, so a CLI run skips its
product assertions rather than failing — see that package's README.
Where an official test surfaced a genuine behavioural gap, the fix went into the
implementation, not the test — e.g. shared_preferences_watchos now throws
TypeError on a wrong-typed read (matching every other platform), and
package_info_plus_watchos now returns installerStore / installTime /
updateTime natively.
These packages were not hand-written from scratch. Each was generated with
the flutter-watchos plugin port tool (part of
flutter-watchos) and then
verified — and where needed finished — by hand.
flutter-watchos plugin port takes an existing Apple plugin (the iOS
implementation package) and emits a federated *_watchos FFI scaffold.
# from a published pub.dev package (what we used):
flutter-watchos plugin port --from-pub shared_preferences_foundation \
--output packages/shared_preferences_watchos --include-example
# or from git, or from a local path:
flutter-watchos plugin port --from-git https://github.com/foo/bar.git --ref main --output ...
flutter-watchos plugin port ../some_plugin_ios --output ...The exact upstream source for each package is recorded at the top of its
PORTING_REPORT.md (e.g. video_player_watchos ←
video_player_avfoundation, shared_preferences_watchos ←
shared_preferences_foundation, audioplayers_watchos ←
audioplayers_darwin).
What the porter does automatically: lays out the federated package
(pubspec, lib/, watchos/, analysis_options.yaml, LICENSE,
CHANGELOG.md), federates through the upstream *_platform_interface,
emits an FFI header/.m scaffold with the C-symbol declarations wired into
flutter.plugin.platforms.watchos.ffiSymbols, generates a
PORTING_REPORT.md recording the source, the watchOS capability outlook
(driven by a watchOS API-availability database), and a checklist, and — with
--include-example — ports the upstream example app and its official
integration_test/ verbatim under a watchOS runner.
Every package gets a PORTING_REPORT.md: the source + version, the watchOS
capability outlook, the FFI surface, every unsupported region with the
reason, and a ## Verification status table. Read it before trusting a port.
The porter emits a scaffold, not a working backend (by design — the
native .m functions are stubs). The real native implementation is written
by hand against the platform interface, following
AUTHORING.md and path_provider_watchos as the reference.
A package only joins the list once it is green:
cd packages/<plugin>_watchos/example
flutter-watchos build watchos --simulator --debug # must be green
cd ..
flutter-watchos test # host unit tests
cd example
flutter-watchos drive \
--driver=test_driver/integration_test.dart \
--target=integration_test/<test-file> -d <watch-sim> # real native code on-simPackages whose primary purpose can't work on watchOS are not shipped — they are documented under Evaluated but not provided rather than published broken.
See AUTHORING.md for the deeper per-plugin recipe.
plugins/
├── packages/<plugin>_watchos/ # one directory per plugin
│ ├── lib/ # Dart (federated impl + FFI bindings)
│ ├── watchos/Classes/ # native FFI (Objective-C, exported C symbols)
│ ├── watchos/Views/ # native SwiftUI platform views (optional)
│ ├── watchos/Package.swift # SwiftPM manifest
│ ├── example/ # upstream example + integration_test, verbatim
│ ├── test/ # host-side unit tests (FFI bindings faked)
│ ├── PORTING_REPORT.md # port detail + verification-status table
│ ├── README.md CHANGELOG.md LICENSE
└── AUTHORING.md # how to add a new one
- Federate via the upstream
*_platform_interface; suffix_watchos. - Ship native code as dart:ffi exported C symbols; method-channel
pluginClass:-only plugins are inert on watchOS. - Guard watchOS-unsupported APIs and document them in the package
README.mdandPORTING_REPORT.mdso users can assess compatibility. - Add host-side unit tests and, where the upstream has one, its official
integration_test/verbatim — fix gaps in the implementation, never the test. - A package only ships if it builds green and verifies on the watch simulator.
BSD-3-Clause — see LICENSE. Ported packages retain their upstream copyright; watchOS additions are © The FlutterWatch Authors.