Skip to main content

native_kit 0.1.1 copy "native_kit: ^0.1.1" to clipboard
native_kit: ^0.1.1 copied to clipboard

One Dart call invokes the real OS-native UI on iOS and Android - system sheets, alerts, zero-permission pickers, scanners, share, print and haptics.

native_kit #

pub package pub points CI platforms license: MIT

One Dart call invokes the real OS-level UI. native_kit presents genuine system view controllers, sheets, zero-permission pickers and hardware scanners on iOS (UIKit / SwiftUI / VisionKit / PencilKit) and Android (Material 3 / Jetpack / ML Kit / system intents) — no Flutter look-alikes, no Swift or Kotlin to write.

NativeKit.showActionSheet opening UIAlertController on iOS and a Material 3 bottom sheet on Android

final choice = await NativeKit.showActionSheet(
  context: context, // anchors the iPad popover + syncs your theme
  items: const [
    NativeMenuItem(id: 'share', title: 'Share', iosSymbol: 'square.and.arrow.up'),
    NativeMenuItem(id: 'delete', title: 'Delete', style: NativeActionStyle.destructive),
  ],
);

Why native_kit #

Drawn by Flutter Drawn by the OS with native_kit
Date picker showDatePicker / CupertinoDatePicker look-alikes UIDatePicker on iOS, MaterialDatePicker on Android
Action sheet & menus Re-created widgets UIAlertController + UIEditMenuInteraction, Material 3 sheets + ListPopupWindow
Color picker Third-party widgets UIColorPickerViewController with the system eyedropper
OS redesigns (e.g. iOS 26 Liquid Glass) Wait for widgets to be re-implemented Picked up from the OS
Photos, contacts, documents Often require permissions Out-of-process system pickers, no permission prompts
Scanners, OCR, subject lift Camera plugin + ML wiring VisionKit / Vision and ML Kit in one call

One dependency covers photo / contact / document pickers, document saving, calendar events, a location picker, share sheet, QuickLook-style preview, in-app browser, printing, translation, dictionary, speech-to-text, biometrics, in-app review, haptics, system panels, document and barcode scanning, OCR, background removal, ink markup and video trimming.

See it run #

The same Dart call on iOS (left) and Android (right), recorded from the example app by its UI test suites:

NativeKit.showAdaptiveSheet with detents on iOS and Android NativeKit.pickDateTime opening UIDatePicker and MaterialDatePicker NativeKit.showAlert destructive confirmation on iOS and Android

Highlights #

  • 30 unified components across 6 domains, 32 typed methods.
  • Clean Dart models — DateTime, Color, Rect, Uint8List and typed result classes. Transport DTOs are never exposed.
  • Context aware — pass a BuildContext and the native UI anchors on that widget (iPad-safe popovers) and follows the Flutter theme's brightness and primary color.
  • No hanging futures — swipe-to-dismiss, back and predictive-back gestures always resolve the call (with null, false or an empty list).
  • No MainActivity changes — Android activity results run through a headless fragment, even with a plain FlutterActivity.
  • Tested on real system UI — XCUITest and UI Automator suites drive every component on the iOS Simulator and an Android emulator.

Installation #

flutter pub add native_kit
import 'package:native_kit/native_kit.dart';

Platform setup #

iOS (16.0+) #

Set platform :ios, '16.0' in ios/Podfile (Swift Package Manager is supported too). Add the usage descriptions for the components you use to ios/Runner/Info.plist:

Key Needed by
NSCameraUsageDescription scanDocument, scanCode, extractLiveText (camera)
NSMicrophoneUsageDescription, NSSpeechRecognitionUsageDescription listenSpeechPrompt
NSFaceIDUsageDescription authenticate on Face ID devices
NSCalendarsUsageDescription createCalendarEvent on iOS 16 only (iOS 17+ needs none)

Missing keys never crash the app: the call throws a NativeKitException with NativeKitErrorCode.missingUsageDescription.

Android (API 26+) #

Set minSdk = 26 in android/app/build.gradle(.kts). That's it: the plugin ships its own manifest entries (a transparent host activity, a FileProvider, package-visibility queries and the install-time INTERNET, VIBRATE and USE_BIOMETRIC permissions). ML Kit models are downloaded by Google Play services on first use.

Architecture #

            ┌──────────────────────── packages/native_kit ────────────────────────┐
 App code ─▶│ NativeKit.showAlert(context: …)  →  domain models → Pigeon DTOs     │
            └──────────────────────────────────┬──────────────────────────────────┘
                                               │ NativeKitPlatform (6 Pigeon host APIs)
            ┌──────────────── native_kit_platform_interface ──────────────────────┐
            │ pigeons/native_kit_api.dart → Dart / Swift / Kotlin                 │
            └───────────────┬─────────────────────────────────┬───────────────────┘
                            ▼                                 ▼
   native_kit_ios (Swift, @MainActor)              native_kit_android (Kotlin, coroutines)
   OverlaysHandler · ValuePickersHandler ·         same 6 handlers, Material 3 + Jetpack,
   ZeroPermPickersHandler · VisionAndMediaHandler  NativeKitResultFragment for every
   SystemUtilitiesHandler · SecurityAndHardware…   ActivityResultContract

Every call carries an optional NativeRect (the calling widget's global rect) and NativeThemeConfig (brightness + seed color) extracted from the BuildContext.

Components #

Module 1 — Overlays #

Dart method iOS Android
showAlert UIAlertController(.alert) + addTextField MaterialAlertDialogBuilder + TextInputEditText
showActionSheet UIAlertController(.actionSheet) (iPad popover) Material 3 BottomSheetDialog list
showContextMenu UIMenu via UIEditMenuInteraction ListPopupWindow at the anchor
showNativeTooltip .popover UIViewController with arrow Material 3 PopupWindow card with arrow
showAdaptiveSheet UISheetPresentationController detents BottomSheetDialog + BottomSheetBehavior

Module 2 — Value pickers #

Dart method iOS Android
pickDateTime / pickDateRange UIDatePicker in a .medium() sheet MaterialDatePicker / MaterialTimePicker
pickColor UIColorPickerViewController (eyedropper, alpha) Material 3 sheet: preview, hex, ARGB / HSL sliders
pickValueWheel multi-column UIPickerView sheet NumberPicker row in a BottomSheetDialog
pickFont UIFontPickerViewController searchable system typeface sheet

Module 3 — Zero-permission pickers #

Dart method iOS Android
pickMedia PHPickerViewController PickVisualMedia / PickMultipleVisualMedia
pickContact CNContactPickerViewController PickContact / ACTION_PICK + ContentResolver
pickDocument UIDocumentPickerViewController(forOpeningContentTypes:asCopy:) OpenDocument / OpenMultipleDocuments
saveDocument UIDocumentPickerViewController(forExporting:asCopy:) CreateDocument + stream write
createCalendarEvent EKEventEditViewController (.ics QuickLook on iOS 16) ACTION_INSERT on CalendarContract.Events
pickLocation MKMapView + MKLocalSearchCompleter sheet map sheet + android.location.Geocoder

Module 4 — Vision & media #

Dart method iOS Android
scanDocument VNDocumentCameraViewController → JPEGs + PDFDocument ML Kit GmsDocumentScanner
scanCode DataScannerViewController / AVCaptureMetadataOutput GmsBarcodeScanner (no camera permission)
extractLiveText VNRecognizeTextRequest / DataScannerViewController(.text()) ML Kit Text Recognition + review sheet
extractImageSubject VNGenerateForegroundInstanceMaskRequest (iOS 17+) ML Kit Subject Segmentation
showMarkupSheet PKCanvasView + PKToolPicker low-latency Canvas full-screen dialog
trimVideo UIVideoEditorController trim sheet with MediaExtractor + MediaMuxer

Module 5 — System utilities #

Dart method iOS Android
share UIActivityViewController Intent.createChooser + FileProvider
previewFile QLPreviewController PdfRenderer pager / ACTION_VIEW
openInAppBrowser SFSafariViewController (.pageSheet) CustomTabsIntent (Partial Custom Tabs)
printDocument UIPrintInteractionController (+ UIMarkupTextPrintFormatter) PrintManager + PrintDocumentAdapter / PrintHelper
showTranslationSheet SwiftUI .translationPresentation (iOS 17.4+) ACTION_PROCESS_TEXT / ACTION_TRANSLATE / TTS sheet
showDictionaryLookUp UIReferenceLibraryViewController ACTION_DEFINE / Partial Custom Tab search
listenSpeechPrompt SFSpeechRecognizer + AVAudioEngine sheet RecognizerIntent.ACTION_RECOGNIZE_SPEECH

Module 6 — Security & hardware #

Dart method iOS Android
authenticate LAContext.evaluatePolicy BiometricPrompt / KeyguardManager
requestAppReview StoreKit AppStore.requestReview(in:) Play ReviewManager (+ store fallback)
triggerHaptic UIImpact/Notification/SelectionFeedbackGenerator, CHHapticEngine HapticFeedbackConstants, VibrationEffect
showSystemPanel AVRoutePickerView, NEHotspotConfigurationManager, MPVolumeView, RPScreenRecorder MediaRouter2 switcher, Settings.Panel.*, MediaProjectionManager

Usage #

// Anchored, themed action sheet (popover on iPad).
final choice = await NativeKit.showActionSheet(
  context: buttonContext,
  items: const [
    NativeMenuItem(id: 'share', title: 'Share', iosSymbol: 'square.and.arrow.up'),
    NativeMenuItem(id: 'delete', title: 'Delete', style: NativeActionStyle.destructive),
  ],
);

// Zero-permission photo picker.
final List<PickedMedia> photos = await NativeKit.pickMedia(
  type: NativeMediaType.images,
  selectionLimit: 5,
);

// Native color picker returns a Flutter Color.
final Color? color = await NativeKit.pickColor(context: context);

// Document scanner returns page JPEGs and a combined PDF.
final DocumentScanResult? scan = await NativeKit.scanDocument();

// The instance API is the same surface, handy for dependency injection.
final NativeKitClient kit = NativeKit.instance;
await kit.triggerHaptic(HapticType.success);

Error handling #

Cancellation is never an error. Real failures throw NativeKitException with a NativeKitErrorCode: noUiContext, unavailable (e.g. VisionKit on the simulator), invalidArgument, missingUsageDescription, permissionDenied, ioError or nativeError.

try {
  await NativeKit.scanCode();
} on NativeKitException catch (e) {
  if (e.code == NativeKitErrorCode.unavailable) showFallbackUi();
}

Platform notes #

  • Files returned to Dart (media, documents, scans, cutouts, trimmed videos) are copies in the app's temporary / cache directory. Move what you keep.
  • pickLocation on Android renders OpenStreetMap tiles by default. Pass androidTileUrlTemplate to use your own tile server in production.
  • showSystemPanel(SystemPanel.screenCapture) records in-app on iOS (call it again to stop and receive the movie) and returns the MediaProjection consent result on Android.
  • showSystemPanel(SystemPanel.nfc) is Android only.

Packages #

Package Purpose
native_kit App-facing API (this package)
native_kit_platform_interface Pigeon contract and NativeKitPlatform
native_kit_ios iOS implementation
native_kit_android Android implementation

License #

MIT — see LICENSE.

Missing a native component? Request it — new components are added to the shared Pigeon bridge for both platforms.

1
likes
160
points
0
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

One Dart call invokes the real OS-native UI on iOS and Android - system sheets, alerts, zero-permission pickers, scanners, share, print and haptics.

Repository (GitHub)
View/report issues
Contributing

Topics

#native #ui #adaptive #modals #pickers

License

MIT (license)

Dependencies

flutter, native_kit_android, native_kit_ios, native_kit_platform_interface

More

Packages that depend on native_kit

Packages that implement native_kit