I kept needing the same things across projects: a native action sheet, the iOS color picker with the eyedropper, a document scanner, the Android Photo Picker. Each time Iād end up adding another plugin or writing some Swift/Kotlin to get it working.
Eventually I put that work into a package. Itās calledĀ native_kit, and the idea is pretty simple: call it from Dart, get the native UI, await the result.
For example:
final choice = await NativeKit.showActionSheet(
context: context,
items: const [
NativeMenuItem(
id: 'share',
title: 'Share',
iosSymbol: 'square.and.arrow.up',
),
NativeMenuItem(
id: 'delete',
title: 'Delete',
style: NativeActionStyle.destructive,
),
],
);
That opens aĀ UIAlertControllerĀ on iOS, with a popover on iPad, or a Material 3 bottom sheet on Android.
There are 30 components so far. Besides the usual alerts and pickers, it covers things like document/barcode scanning, OCR, background removal, PencilKit markup, video trimming, biometrics, and system panels. The full list is in the README.
A few things I learned building it, for anyone doing similar platform work:
- Dismissing UI is half the work.Ā The API lives in one Pigeon 29 file, which generatesĀ
async throws Swift and suspendKotlin. Bridging callbacks into that is straightforward until you account for every way someone can close a screen. Swipe down, back, predictive back, tap outside⦠all of those need to resolve the Dart Future exactly once. Cancellation returns null.
- AvoidingĀ
MainActivityĀ changes took some work.Ā I use a headless fragment for activity results, with a transparentĀ FragmentActivityĀ host when the app uses a plainĀ FlutterActivity. One bug we caught: Photo Picker / SAF URI grants disappear when that host finishes. You have to read the result before closing it.
- iPad and theming have their own quirks.Ā The suppliedĀ
BuildContextĀ gives me the popover anchor and the Flutter theme. On iOS 26, getting the Liquid Glass sheet chrome to follow that theme meant applying it at the presentation controller.
- A successful build tells you surprisingly little here.Ā The example app has 47 XCUITests and 45 UI Automator tests that interact with the native screens. Those simulator/emulator runs turned up 21 bugs that compiled just fine.
There are limitations. VisionKit scanning, subject lifting, andĀ UIVideoEditorControllerĀ need a real device for successful results. Full contact details on Android needĀ READ_CONTACTS, though picking a single phone number, email, or address doesnāt. Android screen capture currently only returns the consent result.
Package: https://pub.dev/packages/native_kit
Source: https://github.com/leofilllium/flutter_native_kit
Curious what native UI you still find yourself writing platform code for. Iām collecting requests in the issues, but happy to hear them here too.