CINXE.COM

Developing | Flutter

<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Developing | Flutter</title><link rel="icon" href="/assets/images/branding/flutter/icon/64.png" eleventy:ignore><link rel="apple-touch-icon" href="/assets/images/branding/flutter/logo/flutter-logomark-320px.png" eleventy:ignore><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="theme-color" content="#ffffff"><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><meta name="google-site-verification" content="HFqxhSbf9YA_0rBglNLzDiWnrHiK_w4cqDh2YD2GEY4"><script>!function(e,t,a,n){e[n]=e[n]||[],e[n].push({"gtm.start":(new Date).getTime(),event:"gtm.js"});var g=t.getElementsByTagName(a)[0],m=t.createElement(a);m.async=!0,m.src="https://www.googletagmanager.com/gtm.js?id=GTM-ND4LWWZ",g.parentNode.insertBefore(m,g)}(window,document,"script","dataLayer")</script><script>!function(e,a,t,n,c,o,s){e.GoogleAnalyticsObject=c,e[c]=e[c]||function(){(e[c].q=e[c].q||[]).push(arguments)},e[c].l=1*new Date,o=a.createElement(t),s=a.getElementsByTagName(t)[0],o.async=1,o.src="//www.google-analytics.com/analytics.js",s.parentNode.insertBefore(o,s)}(window,document,"script",0,"ga"),ga("create","UA-67589403-1","auto"),ga("send","pageview")</script><meta name="description" content="How to write packages and plugins for Flutter."><meta name="twitter:card" content="summary_large_image"><meta name="twitter:site" content="@flutterdev"><meta property="og:title" content="Developing packages &amp; plugins"><meta property="og:url" content="https://docs.flutter.dev/packages-and-plugins/developing-packages"><meta property="og:description" content="How to write packages and plugins for Flutter."><meta property="og:image" content="https://docs.flutter.dev/assets/images/flutter-logo-sharing.png" eleventy:ignore><link href="https://fonts.googleapis.com/css2?family=Google+Sans:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Google+Sans+Text:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Google+Sans+Mono:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" rel="stylesheet"><script>window.__CALLBACKS=[]</script><link rel="stylesheet" href="/assets/css/main.css"></head><body><a href="#site-content-title" id="skip">Skip to main content</a><section id="cookie-notice"><div class="container"><p>docs.flutter.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic. <a href="https://policies.google.com/technologies/cookies" target="_blank" rel="noopener">Learn more</a>.</p><button id="cookie-consent" class="btn btn-primary">OK, got it</button></div></section><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-ND4LWWZ" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript><div id="overlay-under-drawer"></div><header class="site-header"><nav class="navbar navbar-expand-md justify-content-start justify-content-md-between"><button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><i class="material-symbols">menu</i></button> <a class="navbar-brand" href="/"><img src="/assets/images/branding/flutter/logo+text/horizontal/default.svg" alt="Flutter logo" height="37" width="129" class="align-middle"></a><div id="navbarSupportedContent" class="collapse navbar-collapse flex-grow-0"><div class="site-header__sheet-bg" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"></div><div class="site-header__sheet"><ul class="navbar-nav"><div class="site-sidebar site-sidebar--header d-md-none"><ul class="nav flex-column"><li class="nav-header">Get started</li><li class="nav-item"><a class="nav-link" href="/get-started/install">Set up Flutter</a></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-3" role="button" aria-expanded="false" aria-controls="header-sidenav-3">Learn Flutter</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-3"><li class="nav-item"><a class="nav-link" href="/get-started/learn-flutter">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/get-started/codelab">Write your first app</a></li><li class="nav-item"><a class="nav-link collapsible" data-toggle="collapse" data-target="#header-sidenav-3-3" href="#header-sidenav-3-3" role="button" aria-expanded="true" aria-controls="header-sidenav-3-3">Learn the fundamentals</a><ul class="nav flex-column flex-nowrap collapse show" id="header-sidenav-3-3"><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/dart">Intro to Dart</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/widgets">Widgets</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/layout">Layout</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/state-management">State management</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/user-input">Handling user input</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/networking">Networking and data</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/local-caching">Local data and caching</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-3-4" href="/get-started/flutter-for" role="button" aria-expanded="false" aria-controls="header-sidenav-3-4">From another platform?</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-3-4"><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/android-devs">Flutter for Android devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/swiftui-devs">Flutter for SwiftUI devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/uikit-devs">Flutter for UIKit devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/react-native-devs">Flutter for React Native devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/web-devs">Flutter for web devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/xamarin-forms-devs">Flutter for Xamarin.Forms devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/declarative">Introduction to declarative UI</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/dart-swift-concurrency">Flutter versus Swift concurrency</a></li></ul></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link" href="/codelabs">Codelabs</a></li><li class="nav-item"><a class="nav-link" href="/cookbook">Cookbook</a></li><li class="nav-item"><a class="nav-link" href="https://flutter.github.io/samples/" target="_blank" rel="noopener">Demos and samples</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-4" role="button" aria-expanded="false" aria-controls="header-sidenav-4">Stay up to date</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-4"><li class="nav-item"><a class="nav-link" href="/release/upgrade">Upgrade</a></li><li class="nav-item"><a class="nav-link" href="/release/archive">SDK archive</a></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link" href="/release/whats-new">What's new</a></li><li class="nav-item"><a class="nav-link" href="/release/release-notes">Release notes</a></li><li class="nav-item"><a class="nav-link" href="/release/breaking-changes">Breaking changes</a></li><li class="nav-item"><a class="nav-link" href="/release/compatibility-policy">Compatibility policy</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-5" role="button" aria-expanded="false" aria-controls="header-sidenav-5">App solutions</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5"><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-5-1" href="#header-sidenav-5-1" role="button" aria-expanded="false" aria-controls="header-sidenav-5-1">AI</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5-1"><li class="nav-item"><a class="nav-link" href="/resources/ai-overview">Overview</a></li><li class="nav-item"><a class="nav-link" href="https://ai.google.dev/gemini-api/docs/get-started/dart" target="_blank" rel="noopener">Get started with the Gemini API</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/google_generative_ai" target="_blank" rel="noopener">Google AI Dart SDK (pub.dev)</a></li><li class="nav-item"><a class="nav-link" href="https://www.youtube.com/watch?v=1AuzJEiHjO4" target="_blank" rel="noopener">Build with Google AI Dart SDK (video)</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-5-2" href="#header-sidenav-5-2" role="button" aria-expanded="false" aria-controls="header-sidenav-5-2">Firebase & Firestore</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5-2"><li class="nav-item"><a class="nav-link" href="/data-and-backend/firebase">Overview</a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/docs/flutter" target="_blank" rel="noopener">Discover Firebase for Flutter</a></li><li class="nav-item"><a class="nav-link" href="https://www.youtube.com/watch?v=wUSkeTaBonA" target="_blank" rel="noopener">Get to know Firebase for Flutter</a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps" target="_blank" rel="noopener">Add a user authentication flow to a Flutter app using FirebaseUI</a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/codelabs/firebase-get-to-know-web" target="_blank" rel="noopener">Get to know Firebase for web</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-5-3" href="#header-sidenav-5-3" role="button" aria-expanded="false" aria-controls="header-sidenav-5-3">Games</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5-3"><li class="nav-item"><a class="nav-link" href="/resources/games-toolkit">Overview</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/games/achievements-leaderboard">Add achievements and leaderboards</a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/codelabs/build-leaderboards-with-firestore#0" target="_blank" rel="noopener">Build leaderboards with Firestore</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/plugins/google-mobile-ads">Add advertising</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/games/firestore-multiplayer">Add multiplayer support</a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/flutter-in-app-purchases" target="_blank" rel="noopener">Add in-app purchases</a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps" target="_blank" rel="noopener">Add user authentication</a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/docs/crashlytics/get-started?platform=flutter" target="_blank" rel="noopener">Debug using Crashlytics</a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/flutter-flame-brick-breaker" target="_blank" rel="noopener">Intro to Flame with Flutter</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-5-4" href="#header-sidenav-5-4" role="button" aria-expanded="false" aria-controls="header-sidenav-5-4">Monetization</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5-4"><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-5-4-1" href="#header-sidenav-5-4-1" role="button" aria-expanded="false" aria-controls="header-sidenav-5-4-1">Advertising</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5-4-1"><li class="nav-item"><a class="nav-link" href="/resources/ads-overview">Ads overview</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/plugins/google-mobile-ads">Add advertising</a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/admob-ads-in-flutter" target="_blank" rel="noopener">Add AdMob ads to your Flutter app</a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/admob-inline-ads-in-flutter" target="_blank" rel="noopener">Add an AdMob banner and native inline ads</a></li><li class="nav-item"><a class="nav-link" href="https://developers.google.com/admob/flutter/mediation" target="_blank" rel="noopener">Google AdMob mediation</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/interactive_media_ads" target="_blank" rel="noopener">Interactive Media Ads SDK</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-5-4-2" href="#header-sidenav-5-4-2" role="button" aria-expanded="false" aria-controls="header-sidenav-5-4-2">In-app purchases</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5-4-2"><li class="nav-item"><a class="nav-link" href="/resources/in-app-purchases-overview">In-app purchases overview</a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/flutter-in-app-purchases" target="_blank" rel="noopener">Add in-app purchases</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-5-4-3" href="#header-sidenav-5-4-3" role="button" aria-expanded="false" aria-controls="header-sidenav-5-4-3">Payments</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5-4-3"><li class="nav-item"><a class="nav-link" href="/resources/payments-overview">Payments overview</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/pay" target="_blank" rel="noopener">Google pay package</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-5-5" href="#header-sidenav-5-5" role="button" aria-expanded="false" aria-controls="header-sidenav-5-5">Maps</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5-5"><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/google-maps-in-flutter" target="_blank" rel="noopener">Add Google maps to a Flutter app</a></li><li class="nav-item"><a class="nav-link" href="https://developers.google.com/maps/flutter-package" target="_blank" rel="noopener">Google Maps package</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-5-6" href="#header-sidenav-5-6" role="button" aria-expanded="false" aria-controls="header-sidenav-5-6">News</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5-6"><li class="nav-item"><a class="nav-link" href="/resources/news-toolkit">Build a news app</a></li></ul></li></ul></li><li aria-hidden="true"><div class="sidebar-primary-divider"></div></li><li class="nav-header">User interface</li><li class="nav-item"><a class="nav-link" href="/ui">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/ui/widgets">Widget catalog</a></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-10" role="button" aria-expanded="false" aria-controls="header-sidenav-10">Layout</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-10"><li class="nav-item"><a class="nav-link" href="/ui/layout">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/ui/layout/tutorial">Build a layout</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-10-3" href="/ui/layout/lists" role="button" aria-expanded="false" aria-controls="header-sidenav-10-3">Lists & grids</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-10-3"><li class="nav-item"><a class="nav-link" href="/cookbook/lists/basic-list">Create and use lists</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/horizontal-list">Create a horizontal list</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/grid-lists">Create a grid view</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/mixed-list">Create lists with different types of items</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/spaced-items">Create lists with spaced items</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/long-lists">Work with long lists</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-10-4" href="/ui/layout/scrolling" role="button" aria-expanded="false" aria-controls="header-sidenav-10-4">Scrolling</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-10-4"><li class="nav-item"><a class="nav-link" href="/ui/layout/scrolling">Overview</a></li><li class="nav-item"><a class="nav-link" href="/ui/layout/scrolling/slivers">Use slivers to achieve fancy scrolling</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/floating-app-bar">Place a floating app bar above a list</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/effects/parallax-scrolling">Create a scrolling parallax effect</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-11" role="button" aria-expanded="false" aria-controls="header-sidenav-11">Adaptive & responsive design</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-11"><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive">Overview</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/general">General approach</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/safearea-mediaquery">SafeArea & MediaQuery</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/large-screens">Large screens & foldables</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/input">User input & accessibility</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/capabilities">Capabilities & policies</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/best-practices">Best practices</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/more-info">Additional resources</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-12" role="button" aria-expanded="false" aria-controls="header-sidenav-12">Design & theming</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-12"><li class="nav-item"><a class="nav-link" href="/cookbook/design/themes">Share styles with themes</a></li><li class="nav-item"><a class="nav-link" href="/ui/design/material">Material design</a></li><li class="nav-item"><a class="nav-link" href="/release/breaking-changes/material-3-migration">Migrate to Material 3</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-12-4" href="/ui/design/text" role="button" aria-expanded="false" aria-controls="header-sidenav-12-4">Text</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-12-4"><li class="nav-item"><a class="nav-link" href="/ui/design/text/typography">Fonts & typography</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/fonts">Use a custom font</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/package-fonts">Export fonts from a package</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/google_fonts" target="_blank" rel="noopener">Google Fonts package</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-12-5" href="/ui/design/graphics" role="button" aria-expanded="false" aria-controls="header-sidenav-12-5">Custom graphics</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-12-5"><li class="nav-item"><a class="nav-link" href="/ui/design/graphics/fragment-shaders">Use custom fragment shaders</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-13" role="button" aria-expanded="false" aria-controls="header-sidenav-13">Interactivity</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-13"><li class="nav-item"><a class="nav-link" href="/ui/interactivity">Add interactivity to your app</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-13-2" href="/ui/interactivity/gestures" role="button" aria-expanded="false" aria-controls="header-sidenav-13-2">Gestures</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-13-2"><li class="nav-item"><a class="nav-link" href="/ui/interactivity/gestures">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/gestures/handling-taps">Handle taps</a></li><li class="nav-item"><a class="nav-link" href="/ui/interactivity/gestures/drag-outside">Drag an object outside an app</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/effects/drag-a-widget">Drag a UI element within an app</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/gestures/ripples">Add Material touch ripples</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/gestures/dismissible">Implement swipe to dismiss</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-13-3" href="/ui/interactivity/input" role="button" aria-expanded="false" aria-controls="header-sidenav-13-3">Input & forms</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-13-3"><li class="nav-item"><a class="nav-link" href="/cookbook/forms/text-input">Create and style a text field</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/retrieve-input">Retrieve the value of a text field</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/text-field-changes">Handle changes to a text field</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/focus">Manage focus in text fields</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/validation">Build a form with validation</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/snackbars">Display a snackbar</a></li><li class="nav-item"><a class="nav-link" href="/ui/interactivity/actions-and-shortcuts">Implement actions & shortcuts</a></li><li class="nav-item"><a class="nav-link" href="/ui/interactivity/focus">Manage keyboard focus</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-14" role="button" aria-expanded="false" aria-controls="header-sidenav-14">Assets & media</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-14"><li class="nav-item"><a class="nav-link" href="/ui/assets/assets-and-images">Add assets and images</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/images/network-image">Display images from the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/images/fading-in-images">Fade in images with a placeholder</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/plugins/play-video">Play and pause a video</a></li><li class="nav-item"><a class="nav-link" href="/ui/assets/asset-transformation">Transform assets at build time</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-15" role="button" aria-expanded="false" aria-controls="header-sidenav-15">Navigation & routing</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-15"><li class="nav-item"><a class="nav-link" href="/ui/navigation">Overview</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/tabs">Add tabs to your app</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/navigation-basics">Navigate to a new screen and back</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/passing-data">Send data to a new screen</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/returning-data">Return data from a screen</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/drawer">Add a drawer to a screen</a></li><li class="nav-item"><a class="nav-link" href="/ui/navigation/deep-linking">Set up deep linking</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/set-up-app-links">Set up app links for Android</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/set-up-universal-links">Set up universal links for iOS</a></li><li class="nav-item"><a class="nav-link" href="/ui/navigation/url-strategies">Configure web URL strategies</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-16" role="button" aria-expanded="false" aria-controls="header-sidenav-16">Animations & transitions</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-16"><li class="nav-item"><a class="nav-link" href="/ui/animations">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/tutorial">Tutorial</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/implicit-animations">Implicit animations</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/animated-container">Animate the properties of a container</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/opacity-animation">Fade a widget in and out</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/hero-animations">Hero animations</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/page-route-animation">Animate a page route transition</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/physics-simulation">Animate using a physics simulation</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/staggered-animations">Staggered animations</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/effects/staggered-menu-animation">Create a staggered menu animation</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/overview">API overview</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-17" role="button" aria-expanded="false" aria-controls="header-sidenav-17">Accessibility & internationalization</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-17"><li class="nav-item"><a class="nav-link" href="/ui/accessibility-and-internationalization/accessibility">Accessibility</a></li><li class="nav-item"><a class="nav-link" href="/ui/accessibility-and-internationalization/internationalization">Internationalization</a></li></ul></li><li aria-hidden="true"><div class="sidebar-primary-divider"></div></li><li class="nav-header">Beyond UI</li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-20" role="button" aria-expanded="false" aria-controls="header-sidenav-20">Data & backend</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-20"><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-20-1" href="/data-and-backend/state-mgmt" role="button" aria-expanded="false" aria-controls="header-sidenav-20-1">State management</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-20-1"><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/intro">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/declarative">Think declaratively</a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/ephemeral-vs-app">Ephemeral vs app state</a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/simple">Simple app state management</a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/options">Options</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-20-2" href="/data-and-backend/networking" role="button" aria-expanded="false" aria-controls="header-sidenav-20-2">Networking & http</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-20-2"><li class="nav-item"><a class="nav-link" href="/data-and-backend/networking">Overview</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/fetch-data">Fetch data from the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/authenticated-requests">Make authenticated requests</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/send-data">Send data to the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/update-data">Update data over the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/delete-data">Delete data on the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/web-sockets">Communicate with WebSockets</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-20-3" href="/data-and-backend/serialization" role="button" aria-expanded="false" aria-controls="header-sidenav-20-3">Serialization</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-20-3"><li class="nav-item"><a class="nav-link" href="/data-and-backend/serialization/json">JSON serialization</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/background-parsing">Parse JSON in the background</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-20-4" href="/data-and-backend/persistence" role="button" aria-expanded="false" aria-controls="header-sidenav-20-4">Persistence</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-20-4"><li class="nav-item"><a class="nav-link" href="/cookbook/persistence/key-value">Store key-value data on disk</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/persistence/reading-writing-files">Read and write files</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/persistence/sqlite">Persist data with SQLite</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-20-5" href="/data-and-backend/firebase" role="button" aria-expanded="false" aria-controls="header-sidenav-20-5">Firebase</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-20-5"><li class="nav-item"><a class="nav-link" href="/data-and-backend/firebase">Overview</a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/docs/flutter/setup" target="_blank" rel="noopener">Add Firebase to your Flutter app</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/google-apis">Google APIs</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-21" role="button" aria-expanded="false" aria-controls="header-sidenav-21">App architecture</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-21"><li class="nav-item"><a class="nav-link" href="/app-architecture">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/concepts">Architecture concepts</a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/guide">Guide to app architecture</a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/recommendations">Recommendations</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-21-5" href="/cookbook/architecture" role="button" aria-expanded="false" aria-controls="header-sidenav-21-5">Design patterns</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-21-5"><li class="nav-item"><a class="nav-link" href="/cookbook/architecture/optimistic-state">Optimistic state</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/architecture/key-value-data">Persistent storage architecture: Key-value data</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/architecture/sql">Persistent storage architecture: SQL</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/architecture/offline-first">Offline-first</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-22" role="button" aria-expanded="false" aria-controls="header-sidenav-22">Platform integration</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-22"><li class="nav-item"><a class="nav-link" href="/reference/supported-platforms">Supported platforms</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/desktop">Build desktop apps with Flutter</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/platform-channels">Write platform-specific code</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/platform-adaptations">Automatic platform adaptations</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-22-5" href="/platform-integration/android" role="button" aria-expanded="false" aria-controls="header-sidenav-22-5">Android</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-22-5"><li class="nav-item"><a class="nav-link" href="/platform-integration/android/install-android">Add Android as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/splash-screen">Add a splash screen</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/predictive-back">Add predictive back</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/c-interop">Bind to native code</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/platform-views">Host a native Android view</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/compose-activity">Launch a Jetpack Compose activity</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/restore-state-android">Restore state on Android</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/chromeos">Target ChromeOS with Android</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-22-6" href="/platform-integration/ios" role="button" aria-expanded="false" aria-controls="header-sidenav-22-6">iOS</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-22-6"><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/install-ios">Add iOS as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/ios-latest">Flutter on latest iOS</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/apple-frameworks">Leverage Apple's system libraries</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/launch-screen">Add a launch screen</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/ios-app-clip">Add iOS App Clip support</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/app-extensions">Add iOS app extensions</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/c-interop">Bind to native code</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/platform-views">Host a native iOS view</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/ios-debugging">Enable debugging on iOS</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/restore-state-ios">Restore state on iOS</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-22-7" href="/platform-integration/linux" role="button" aria-expanded="false" aria-controls="header-sidenav-22-7">Linux</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-22-7"><li class="nav-item"><a class="nav-link" href="/platform-integration/linux/install-linux">Add Linux as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/linux/building">Build a Linux app</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-22-8" href="/platform-integration/macos" role="button" aria-expanded="false" aria-controls="header-sidenav-22-8">macOS</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-22-8"><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/install-macos">Add macOS as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/building">Build a macOS app</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/c-interop">Bind to native code</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/platform-views">Host a native macOS view</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-22-9" href="/platform-integration/web" role="button" aria-expanded="false" aria-controls="header-sidenav-22-9">Web</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-22-9"><li class="nav-item"><a class="nav-link" href="/platform-integration/web/">Web support in Flutter</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/install-web">Add web as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/building">Build a web app</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/wasm">Compile to WebAssembly</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/initialization">Customize app initialization</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/embedding-flutter-web">Add Flutter to any web app</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/web-content-in-flutter">Web content in Flutter</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/renderers">Web renderers</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/web-images">Display images on the web</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/faq">Web FAQ</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-22-10" href="/platform-integration/windows" role="button" aria-expanded="false" aria-controls="header-sidenav-22-10">Windows</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-22-10"><li class="nav-item"><a class="nav-link" href="/platform-integration/windows/install-windows">Add Windows as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/windows/building">Build a Windows app</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link active collapsible" data-toggle="collapse" href="#header-sidenav-23" role="button" aria-expanded="true" aria-controls="header-sidenav-23">Packages & plugins</a><ul class="nav flex-column flex-nowrap collapse show" id="header-sidenav-23"><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/using-packages">Use packages & plugins</a></li><li class="nav-item"><a class="nav-link active" href="/packages-and-plugins/developing-packages">Develop packages & plugins</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-23-3" href="/packages-and-plugins/swift-package-manager" role="button" aria-expanded="false" aria-controls="header-sidenav-23-3">Swift Package Manager</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-23-3"><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/swift-package-manager/for-app-developers">For app developers</a></li><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/swift-package-manager/for-plugin-authors">For plugin authors</a></li></ul></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/favorites">Flutter Favorites</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/flutter" target="_blank" rel="noopener">Package repository</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-24" role="button" aria-expanded="false" aria-controls="header-sidenav-24">Testing & debugging</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-24"><li class="nav-header">Testing</li><li class="nav-item"><a class="nav-link" href="/testing/overview">Overview</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-24-3" href="#header-sidenav-24-3" role="button" aria-expanded="false" aria-controls="header-sidenav-24-3">Unit testing</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-24-3"><li class="nav-item"><a class="nav-link" href="/cookbook/testing/unit/introduction">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/unit/mocking">Mock dependencies</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-24-4" href="#header-sidenav-24-4" role="button" aria-expanded="false" aria-controls="header-sidenav-24-4">Widget testing</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-24-4"><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/introduction">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/finders">Find widgets</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/scrolling">Simulate scrolling</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/tap-drag">Simulate user interaction</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-24-5" href="#header-sidenav-24-5" role="button" aria-expanded="false" aria-controls="header-sidenav-24-5">Integration testing</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-24-5"><li class="nav-item"><a class="nav-link" href="/cookbook/testing/integration/introduction">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/testing/integration-tests">Write and run an integration test</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/integration/profiling">Profile an integration test</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/testing/testing-plugins">Test a plugin</a></li><li class="nav-item"><a class="nav-link" href="/testing/plugins-in-tests">Handle plugin code in tests</a></li><li class="nav-header">Debugging</li><li class="nav-item"><a class="nav-link" href="/testing/debugging">Debugging tools</a></li><li class="nav-item"><a class="nav-link" href="/testing/code-debugging">Debug your app programmatically</a></li><li class="nav-item"><a class="nav-link" href="/testing/native-debugging">Use a native language debugger</a></li><li class="nav-item"><a class="nav-link" href="/testing/build-modes">Flutter's build modes</a></li><li class="nav-item"><a class="nav-link" href="/testing/common-errors">Common Flutter errors</a></li><li class="nav-item"><a class="nav-link" href="/testing/errors">Handle errors</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/maintenance/error-reporting">Report errors to a service</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-25" role="button" aria-expanded="false" aria-controls="header-sidenav-25">Performance & optimization</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-25"><li class="nav-item"><a class="nav-link" href="/perf">Overview</a></li><li class="nav-item"><a class="nav-link" href="/perf/impeller">Impeller</a></li><li class="nav-item"><a class="nav-link" href="/perf/best-practices">Performance best practices</a></li><li class="nav-item"><a class="nav-link" href="/perf/app-size">App size</a></li><li class="nav-item"><a class="nav-link" href="/perf/deferred-components">Deferred components</a></li><li class="nav-item"><a class="nav-link" href="/perf/rendering-performance">Rendering performance</a></li><li class="nav-item"><a class="nav-link" href="/perf/ui-performance">Performance profiling</a></li><li class="nav-item"><a class="nav-link" href="/perf/web-performance">Performance profiling for web</a></li><li class="nav-item"><a class="nav-link" href="/perf/shader">Shader compilation jank</a></li><li class="nav-item"><a class="nav-link" href="/perf/metrics">Performance metrics</a></li><li class="nav-item"><a class="nav-link" href="/perf/isolates">Concurrency and isolates</a></li><li class="nav-item"><a class="nav-link" href="/perf/faq">Performance FAQ</a></li><li class="nav-item"><a class="nav-link" href="/perf/appendix">Appendix</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-26" role="button" aria-expanded="false" aria-controls="header-sidenav-26">Deployment</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-26"><li class="nav-item"><a class="nav-link" href="/deployment/obfuscate">Obfuscate Dart code</a></li><li class="nav-item"><a class="nav-link" href="/deployment/flavors">Create flavors of an app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/android">Build and release an Android app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/ios">Build and release an iOS app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/macos">Build and release a macOS app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/linux">Build and release a Linux app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/windows">Build and release a Windows app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/web">Build and release a web app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/cd">Set up continuous deployment</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-27" role="button" aria-expanded="false" aria-controls="header-sidenav-27">Add to an existing app</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-27"><li class="nav-item"><a class="nav-link" href="/add-to-app">Introduction</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-27-2" href="/add-to-app/android" role="button" aria-expanded="false" aria-controls="header-sidenav-27-2">Add to an Android app</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-27-2"><li class="nav-item"><a class="nav-link" href="/add-to-app/android/project-setup">Set up Android project</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/add-flutter-screen">Add a single Flutter screen</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/add-flutter-fragment">Add a Flutter Fragment</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/add-flutter-view">Add a Flutter View</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/plugin-setup">Use a Flutter plugin</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-27-3" href="/add-to-app/ios" role="button" aria-expanded="false" aria-controls="header-sidenav-27-3">Add to an iOS app</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-27-3"><li class="nav-item"><a class="nav-link" href="/add-to-app/ios/project-setup">Set up iOS project</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/ios/add-flutter-screen">Add a single Flutter screen</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/embedding-flutter-web">Add to a web app</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/debugging">Debug embedded Flutter module</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/multiple-flutters">Add multiple Flutter instances</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/performance">Loading sequence and performance</a></li></ul></li><li aria-hidden="true"><div class="sidebar-primary-divider"></div></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-29" role="button" aria-expanded="false" aria-controls="header-sidenav-29">Tools & editors</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-29"><li class="nav-item"><a class="nav-link" href="/tools/android-studio">Android Studio & IntelliJ</a></li><li class="nav-item"><a class="nav-link" href="/tools/vs-code">Visual Studio Code</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-29-3" href="/tools/devtools" role="button" aria-expanded="false" aria-controls="header-sidenav-29-3">DevTools</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-29-3"><li class="nav-item"><a class="nav-link" href="/tools/devtools">Overview</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/android-studio">Run from Android Studio & IntelliJ</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/vscode">Run from VS Code</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/cli">Run from command line</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/inspector">Flutter inspector</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/performance">Performance view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/cpu-profiler">CPU Profiler view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/memory">Memory view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/console">Debug console view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/network">Network view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/debugger">Debugger</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/logging">Logging view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/app-size">App size tool</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/extensions">DevTools extensions</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/deep-links">Validate deep links</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/release-notes">Release notes</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/tools/sdk">SDK overview</a></li><li class="nav-item"><a class="nav-link" href="/tools/pubspec">Flutter's pubspec options</a></li><li class="nav-item"><a class="nav-link" href="/tools/flutter-fix">Automated fixes</a></li><li class="nav-item"><a class="nav-link" href="/tools/formatting">Code formatting</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-30" role="button" aria-expanded="false" aria-controls="header-sidenav-30">Flutter concepts</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-30"><li class="nav-item"><a class="nav-link" href="/resources/architectural-overview">Architectural overview</a></li><li class="nav-item"><a class="nav-link" href="/resources/inside-flutter">Inside Flutter</a></li><li class="nav-item"><a class="nav-link" href="/ui/layout/constraints">Understanding constraints</a></li><li class="nav-item"><a class="nav-link" href="/testing/build-modes">Flutter's build modes</a></li><li class="nav-item"><a class="nav-link" href="/tools/hot-reload">Hot reload</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-31" role="button" aria-expanded="false" aria-controls="header-sidenav-31">Resources</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-31"><li class="nav-item"><a class="nav-link" href="/resources/faq">FAQ</a></li><li class="nav-item"><a class="nav-link" href="/resources/books">Books</a></li><li class="nav-item"><a class="nav-link" href="/resources/videos">Videos</a></li><li class="nav-item"><a class="nav-link" href="/resources/courses">Courses</a></li><li class="nav-item"><a class="nav-link" href="/resources/bootstrap-into-dart">Learn Dart</a></li><li class="nav-item"><a class="nav-link" href="/resources/support">Get support</a></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-31-8" href="#header-sidenav-31-8" role="button" aria-expanded="false" aria-controls="header-sidenav-31-8">Contribute</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-31-8"><li class="nav-item"><a class="nav-link" href="/resources/bug-reports">Create useful bug reports</a></li><li class="nav-item"><a class="nav-link" href="https://github.com/flutter/flutter/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener">Contribute to Flutter</a></li><li class="nav-item"><a class="nav-link" href="/resources/design-docs">Discover proposed features</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-31-9" href="/reference" role="button" aria-expanded="false" aria-controls="header-sidenav-31-9">Reference</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-31-9"><li class="nav-item"><a class="nav-link" href="/dash">Who is Dash?</a></li><li class="nav-item"><a class="nav-link" href="/reference/widgets">Widget index</a></li><li class="nav-item"><a class="nav-link" href="/reference/flutter-cli">flutter CLI</a></li><li class="nav-item"><a class="nav-link" href="https://api.flutter.dev" target="_blank" rel="noopener">API docs</a></li></ul></li></ul></li></ul></div><li class="nav-item dropdown"><a class="nav-link dropdown-toggle" id="platform-navbar-dropdown" href="https://flutter.dev/multi-platform" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Multi-Platform</a><div class="dropdown-menu" aria-labelledby="platform-navbar-dropdown"><a class="dropdown-item" href="https://flutter.dev/multi-platform/mobile">Mobile</a> <a class="dropdown-item" href="https://flutter.dev/multi-platform/web">Web</a> <a class="dropdown-item" href="https://flutter.dev/multi-platform/desktop">Desktop</a> <a class="dropdown-item" href="https://flutter.dev/multi-platform/embedded">Embedded</a></div></li><li class="nav-item dropdown"><a class="nav-link dropdown-toggle" id="dev-navbar-dropdown" href="https://flutter.dev/" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Development</a><div class="dropdown-menu" aria-labelledby="dev-navbar-dropdown"><a class="dropdown-item" href="https://flutter.dev/learn">Learn</a> <a class="dropdown-item" href="https://pub.dev/flutter/favorites" target="_blank">Flutter Favorites</a> <a class="dropdown-item" href="https://pub.dev/" target="_blank">Packages</a> <a class="dropdown-item" href="https://flutter.dev/monetization">Monetization</a> <a class="dropdown-item" href="https://flutter.dev/games">Games</a> <a class="dropdown-item" href="https://flutter.dev/news">News</a></div></li><li class="nav-item dropdown"><a class="nav-link dropdown-toggle" id="ecosystem-navbar-dropdown" href="https://flutter.dev/ecosystem" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Ecosystem</a><div class="dropdown-menu" aria-labelledby="ecosystem-navbar-dropdown"><a class="dropdown-item" href="https://flutter.dev/community">Community</a> <a class="dropdown-item" href="https://flutter.dev/events">Events</a> <a class="dropdown-item" href="https://flutter.dev/culture">Culture</a></div></li><li class="nav-item"><a class="nav-link" href="https://flutter.dev/showcase">Showcase</a></li><li class="nav-item dropdown docs-item"><a class="nav-link dropdown-toggle" id="docs-navbar-dropdown" href="/" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Docs</a><div class="dropdown-menu" aria-labelledby="docs-navbar-dropdown"><a class="dropdown-item" href="/release/whats-new">What's new</a> <a class="dropdown-item" href="/get-started/editor">Editor support</a> <a class="dropdown-item" href="/tools/hot-reload">Hot reload</a> <a class="dropdown-item" href="/perf/ui-performance">Profiling</a> <a class="dropdown-item" href="/get-started/install">Install Flutter</a> <a class="dropdown-item" href="/tools/devtools">DevTools</a> <a class="dropdown-item" href="/cookbook">Cookbook</a> <a class="dropdown-item" href="/codelabs">Codelabs</a></div></li></ul><form action="/search/" class="site-header__search form-inline"><input class="site-header__searchfield form-control search-field" type="search" name="q" id="q" autocomplete="off" placeholder="Search" aria-label="Search"></form></div></div><div class="site-header__social navbar-nav flex-row"><a class="nav-item nav-link nav-icon" href="https://twitter.com/FlutterDev" aria-label="Open Flutter's X (Twitter) in a new tab" target="_blank" rel="noreferrer"><svg><use href="/assets/images/social/x.svg#x"></use></svg> </a><a class="nav-item nav-link nav-icon" href="https://www.youtube.com/@flutterdev" aria-label="Open Flutter's YouTube in a new tab" target="_blank" rel="noreferrer"><svg><use href="/assets/images/social/youtube.svg#youtube"></use></svg> </a><a class="nav-item nav-link nav-icon" href="https://medium.com/flutter" aria-label="Open Flutter's Medium blog in a new tab" target="_blank" rel="noreferrer"><svg><use href="/assets/images/social/medium.svg#medium"></use></svg> </a><a class="nav-item nav-link nav-icon" href="https://github.com/flutter" aria-label="Open Flutter's GitHub in a new tab" target="_blank" rel="noreferrer"><svg><use href="/assets/images/social/github.svg#github"></use></svg></a></div><a class="site-header__cta btn btn-primary" href="/get-started/install/">Get started</a></nav></header><div class="site-banner site-banner--default" role="alert"><a href="https://medium.com/flutter/flutter-3-24-dart-3-5-204b7d20c45d">Flutter 3.24 and Dart 3.5</a> are here! Check out <a href="/release/whats-new">what's new</a> on the website.</div><div class="container-fluid position-relative"><div class="row flex-xl-nowrap"><div class="fixed-col site-sidebar site-sidebar--fixed col-12 col-md-3 col-xl-2 d-none d-md-block" data-fixed-column><ul class="nav flex-column"><li class="nav-header">Get started</li><li class="nav-item"><a class="nav-link" href="/get-started/install">Set up Flutter</a></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-3" role="button" aria-expanded="false" aria-controls="fixed-sidenav-3">Learn Flutter</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-3"><li class="nav-item"><a class="nav-link" href="/get-started/learn-flutter">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/get-started/codelab">Write your first app</a></li><li class="nav-item"><a class="nav-link collapsible" data-toggle="collapse" data-target="#fixed-sidenav-3-3" href="#fixed-sidenav-3-3" role="button" aria-expanded="true" aria-controls="fixed-sidenav-3-3">Learn the fundamentals</a><ul class="nav flex-column flex-nowrap collapse show" id="fixed-sidenav-3-3"><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/dart">Intro to Dart</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/widgets">Widgets</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/layout">Layout</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/state-management">State management</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/user-input">Handling user input</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/networking">Networking and data</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/local-caching">Local data and caching</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-3-4" href="/get-started/flutter-for" role="button" aria-expanded="false" aria-controls="fixed-sidenav-3-4">From another platform?</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-3-4"><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/android-devs">Flutter for Android devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/swiftui-devs">Flutter for SwiftUI devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/uikit-devs">Flutter for UIKit devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/react-native-devs">Flutter for React Native devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/web-devs">Flutter for web devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/xamarin-forms-devs">Flutter for Xamarin.Forms devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/declarative">Introduction to declarative UI</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/dart-swift-concurrency">Flutter versus Swift concurrency</a></li></ul></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link" href="/codelabs">Codelabs</a></li><li class="nav-item"><a class="nav-link" href="/cookbook">Cookbook</a></li><li class="nav-item"><a class="nav-link" href="https://flutter.github.io/samples/" target="_blank" rel="noopener">Demos and samples</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-4" role="button" aria-expanded="false" aria-controls="fixed-sidenav-4">Stay up to date</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-4"><li class="nav-item"><a class="nav-link" href="/release/upgrade">Upgrade</a></li><li class="nav-item"><a class="nav-link" href="/release/archive">SDK archive</a></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link" href="/release/whats-new">What's new</a></li><li class="nav-item"><a class="nav-link" href="/release/release-notes">Release notes</a></li><li class="nav-item"><a class="nav-link" href="/release/breaking-changes">Breaking changes</a></li><li class="nav-item"><a class="nav-link" href="/release/compatibility-policy">Compatibility policy</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-5" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5">App solutions</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5"><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-5-1" href="#fixed-sidenav-5-1" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5-1">AI</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5-1"><li class="nav-item"><a class="nav-link" href="/resources/ai-overview">Overview</a></li><li class="nav-item"><a class="nav-link" href="https://ai.google.dev/gemini-api/docs/get-started/dart" target="_blank" rel="noopener">Get started with the Gemini API</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/google_generative_ai" target="_blank" rel="noopener">Google AI Dart SDK (pub.dev)</a></li><li class="nav-item"><a class="nav-link" href="https://www.youtube.com/watch?v=1AuzJEiHjO4" target="_blank" rel="noopener">Build with Google AI Dart SDK (video)</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-5-2" href="#fixed-sidenav-5-2" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5-2">Firebase & Firestore</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5-2"><li class="nav-item"><a class="nav-link" href="/data-and-backend/firebase">Overview</a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/docs/flutter" target="_blank" rel="noopener">Discover Firebase for Flutter</a></li><li class="nav-item"><a class="nav-link" href="https://www.youtube.com/watch?v=wUSkeTaBonA" target="_blank" rel="noopener">Get to know Firebase for Flutter</a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps" target="_blank" rel="noopener">Add a user authentication flow to a Flutter app using FirebaseUI</a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/codelabs/firebase-get-to-know-web" target="_blank" rel="noopener">Get to know Firebase for web</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-5-3" href="#fixed-sidenav-5-3" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5-3">Games</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5-3"><li class="nav-item"><a class="nav-link" href="/resources/games-toolkit">Overview</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/games/achievements-leaderboard">Add achievements and leaderboards</a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/codelabs/build-leaderboards-with-firestore#0" target="_blank" rel="noopener">Build leaderboards with Firestore</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/plugins/google-mobile-ads">Add advertising</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/games/firestore-multiplayer">Add multiplayer support</a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/flutter-in-app-purchases" target="_blank" rel="noopener">Add in-app purchases</a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps" target="_blank" rel="noopener">Add user authentication</a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/docs/crashlytics/get-started?platform=flutter" target="_blank" rel="noopener">Debug using Crashlytics</a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/flutter-flame-brick-breaker" target="_blank" rel="noopener">Intro to Flame with Flutter</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-5-4" href="#fixed-sidenav-5-4" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5-4">Monetization</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5-4"><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-5-4-1" href="#fixed-sidenav-5-4-1" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5-4-1">Advertising</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5-4-1"><li class="nav-item"><a class="nav-link" href="/resources/ads-overview">Ads overview</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/plugins/google-mobile-ads">Add advertising</a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/admob-ads-in-flutter" target="_blank" rel="noopener">Add AdMob ads to your Flutter app</a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/admob-inline-ads-in-flutter" target="_blank" rel="noopener">Add an AdMob banner and native inline ads</a></li><li class="nav-item"><a class="nav-link" href="https://developers.google.com/admob/flutter/mediation" target="_blank" rel="noopener">Google AdMob mediation</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/interactive_media_ads" target="_blank" rel="noopener">Interactive Media Ads SDK</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-5-4-2" href="#fixed-sidenav-5-4-2" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5-4-2">In-app purchases</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5-4-2"><li class="nav-item"><a class="nav-link" href="/resources/in-app-purchases-overview">In-app purchases overview</a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/flutter-in-app-purchases" target="_blank" rel="noopener">Add in-app purchases</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-5-4-3" href="#fixed-sidenav-5-4-3" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5-4-3">Payments</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5-4-3"><li class="nav-item"><a class="nav-link" href="/resources/payments-overview">Payments overview</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/pay" target="_blank" rel="noopener">Google pay package</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-5-5" href="#fixed-sidenav-5-5" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5-5">Maps</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5-5"><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/google-maps-in-flutter" target="_blank" rel="noopener">Add Google maps to a Flutter app</a></li><li class="nav-item"><a class="nav-link" href="https://developers.google.com/maps/flutter-package" target="_blank" rel="noopener">Google Maps package</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-5-6" href="#fixed-sidenav-5-6" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5-6">News</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5-6"><li class="nav-item"><a class="nav-link" href="/resources/news-toolkit">Build a news app</a></li></ul></li></ul></li><li aria-hidden="true"><div class="sidebar-primary-divider"></div></li><li class="nav-header">User interface</li><li class="nav-item"><a class="nav-link" href="/ui">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/ui/widgets">Widget catalog</a></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-10" role="button" aria-expanded="false" aria-controls="fixed-sidenav-10">Layout</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-10"><li class="nav-item"><a class="nav-link" href="/ui/layout">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/ui/layout/tutorial">Build a layout</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-10-3" href="/ui/layout/lists" role="button" aria-expanded="false" aria-controls="fixed-sidenav-10-3">Lists & grids</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-10-3"><li class="nav-item"><a class="nav-link" href="/cookbook/lists/basic-list">Create and use lists</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/horizontal-list">Create a horizontal list</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/grid-lists">Create a grid view</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/mixed-list">Create lists with different types of items</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/spaced-items">Create lists with spaced items</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/long-lists">Work with long lists</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-10-4" href="/ui/layout/scrolling" role="button" aria-expanded="false" aria-controls="fixed-sidenav-10-4">Scrolling</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-10-4"><li class="nav-item"><a class="nav-link" href="/ui/layout/scrolling">Overview</a></li><li class="nav-item"><a class="nav-link" href="/ui/layout/scrolling/slivers">Use slivers to achieve fancy scrolling</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/floating-app-bar">Place a floating app bar above a list</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/effects/parallax-scrolling">Create a scrolling parallax effect</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-11" role="button" aria-expanded="false" aria-controls="fixed-sidenav-11">Adaptive & responsive design</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-11"><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive">Overview</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/general">General approach</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/safearea-mediaquery">SafeArea & MediaQuery</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/large-screens">Large screens & foldables</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/input">User input & accessibility</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/capabilities">Capabilities & policies</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/best-practices">Best practices</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/more-info">Additional resources</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-12" role="button" aria-expanded="false" aria-controls="fixed-sidenav-12">Design & theming</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-12"><li class="nav-item"><a class="nav-link" href="/cookbook/design/themes">Share styles with themes</a></li><li class="nav-item"><a class="nav-link" href="/ui/design/material">Material design</a></li><li class="nav-item"><a class="nav-link" href="/release/breaking-changes/material-3-migration">Migrate to Material 3</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-12-4" href="/ui/design/text" role="button" aria-expanded="false" aria-controls="fixed-sidenav-12-4">Text</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-12-4"><li class="nav-item"><a class="nav-link" href="/ui/design/text/typography">Fonts & typography</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/fonts">Use a custom font</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/package-fonts">Export fonts from a package</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/google_fonts" target="_blank" rel="noopener">Google Fonts package</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-12-5" href="/ui/design/graphics" role="button" aria-expanded="false" aria-controls="fixed-sidenav-12-5">Custom graphics</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-12-5"><li class="nav-item"><a class="nav-link" href="/ui/design/graphics/fragment-shaders">Use custom fragment shaders</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-13" role="button" aria-expanded="false" aria-controls="fixed-sidenav-13">Interactivity</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-13"><li class="nav-item"><a class="nav-link" href="/ui/interactivity">Add interactivity to your app</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-13-2" href="/ui/interactivity/gestures" role="button" aria-expanded="false" aria-controls="fixed-sidenav-13-2">Gestures</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-13-2"><li class="nav-item"><a class="nav-link" href="/ui/interactivity/gestures">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/gestures/handling-taps">Handle taps</a></li><li class="nav-item"><a class="nav-link" href="/ui/interactivity/gestures/drag-outside">Drag an object outside an app</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/effects/drag-a-widget">Drag a UI element within an app</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/gestures/ripples">Add Material touch ripples</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/gestures/dismissible">Implement swipe to dismiss</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-13-3" href="/ui/interactivity/input" role="button" aria-expanded="false" aria-controls="fixed-sidenav-13-3">Input & forms</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-13-3"><li class="nav-item"><a class="nav-link" href="/cookbook/forms/text-input">Create and style a text field</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/retrieve-input">Retrieve the value of a text field</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/text-field-changes">Handle changes to a text field</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/focus">Manage focus in text fields</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/validation">Build a form with validation</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/snackbars">Display a snackbar</a></li><li class="nav-item"><a class="nav-link" href="/ui/interactivity/actions-and-shortcuts">Implement actions & shortcuts</a></li><li class="nav-item"><a class="nav-link" href="/ui/interactivity/focus">Manage keyboard focus</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-14" role="button" aria-expanded="false" aria-controls="fixed-sidenav-14">Assets & media</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-14"><li class="nav-item"><a class="nav-link" href="/ui/assets/assets-and-images">Add assets and images</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/images/network-image">Display images from the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/images/fading-in-images">Fade in images with a placeholder</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/plugins/play-video">Play and pause a video</a></li><li class="nav-item"><a class="nav-link" href="/ui/assets/asset-transformation">Transform assets at build time</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-15" role="button" aria-expanded="false" aria-controls="fixed-sidenav-15">Navigation & routing</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-15"><li class="nav-item"><a class="nav-link" href="/ui/navigation">Overview</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/tabs">Add tabs to your app</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/navigation-basics">Navigate to a new screen and back</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/passing-data">Send data to a new screen</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/returning-data">Return data from a screen</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/drawer">Add a drawer to a screen</a></li><li class="nav-item"><a class="nav-link" href="/ui/navigation/deep-linking">Set up deep linking</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/set-up-app-links">Set up app links for Android</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/set-up-universal-links">Set up universal links for iOS</a></li><li class="nav-item"><a class="nav-link" href="/ui/navigation/url-strategies">Configure web URL strategies</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-16" role="button" aria-expanded="false" aria-controls="fixed-sidenav-16">Animations & transitions</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-16"><li class="nav-item"><a class="nav-link" href="/ui/animations">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/tutorial">Tutorial</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/implicit-animations">Implicit animations</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/animated-container">Animate the properties of a container</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/opacity-animation">Fade a widget in and out</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/hero-animations">Hero animations</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/page-route-animation">Animate a page route transition</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/physics-simulation">Animate using a physics simulation</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/staggered-animations">Staggered animations</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/effects/staggered-menu-animation">Create a staggered menu animation</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/overview">API overview</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-17" role="button" aria-expanded="false" aria-controls="fixed-sidenav-17">Accessibility & internationalization</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-17"><li class="nav-item"><a class="nav-link" href="/ui/accessibility-and-internationalization/accessibility">Accessibility</a></li><li class="nav-item"><a class="nav-link" href="/ui/accessibility-and-internationalization/internationalization">Internationalization</a></li></ul></li><li aria-hidden="true"><div class="sidebar-primary-divider"></div></li><li class="nav-header">Beyond UI</li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-20" role="button" aria-expanded="false" aria-controls="fixed-sidenav-20">Data & backend</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-20"><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-20-1" href="/data-and-backend/state-mgmt" role="button" aria-expanded="false" aria-controls="fixed-sidenav-20-1">State management</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-20-1"><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/intro">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/declarative">Think declaratively</a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/ephemeral-vs-app">Ephemeral vs app state</a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/simple">Simple app state management</a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/options">Options</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-20-2" href="/data-and-backend/networking" role="button" aria-expanded="false" aria-controls="fixed-sidenav-20-2">Networking & http</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-20-2"><li class="nav-item"><a class="nav-link" href="/data-and-backend/networking">Overview</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/fetch-data">Fetch data from the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/authenticated-requests">Make authenticated requests</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/send-data">Send data to the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/update-data">Update data over the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/delete-data">Delete data on the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/web-sockets">Communicate with WebSockets</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-20-3" href="/data-and-backend/serialization" role="button" aria-expanded="false" aria-controls="fixed-sidenav-20-3">Serialization</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-20-3"><li class="nav-item"><a class="nav-link" href="/data-and-backend/serialization/json">JSON serialization</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/background-parsing">Parse JSON in the background</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-20-4" href="/data-and-backend/persistence" role="button" aria-expanded="false" aria-controls="fixed-sidenav-20-4">Persistence</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-20-4"><li class="nav-item"><a class="nav-link" href="/cookbook/persistence/key-value">Store key-value data on disk</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/persistence/reading-writing-files">Read and write files</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/persistence/sqlite">Persist data with SQLite</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-20-5" href="/data-and-backend/firebase" role="button" aria-expanded="false" aria-controls="fixed-sidenav-20-5">Firebase</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-20-5"><li class="nav-item"><a class="nav-link" href="/data-and-backend/firebase">Overview</a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/docs/flutter/setup" target="_blank" rel="noopener">Add Firebase to your Flutter app</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/google-apis">Google APIs</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-21" role="button" aria-expanded="false" aria-controls="fixed-sidenav-21">App architecture</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-21"><li class="nav-item"><a class="nav-link" href="/app-architecture">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/concepts">Architecture concepts</a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/guide">Guide to app architecture</a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/recommendations">Recommendations</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-21-5" href="/cookbook/architecture" role="button" aria-expanded="false" aria-controls="fixed-sidenav-21-5">Design patterns</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-21-5"><li class="nav-item"><a class="nav-link" href="/cookbook/architecture/optimistic-state">Optimistic state</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/architecture/key-value-data">Persistent storage architecture: Key-value data</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/architecture/sql">Persistent storage architecture: SQL</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/architecture/offline-first">Offline-first</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-22" role="button" aria-expanded="false" aria-controls="fixed-sidenav-22">Platform integration</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-22"><li class="nav-item"><a class="nav-link" href="/reference/supported-platforms">Supported platforms</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/desktop">Build desktop apps with Flutter</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/platform-channels">Write platform-specific code</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/platform-adaptations">Automatic platform adaptations</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-22-5" href="/platform-integration/android" role="button" aria-expanded="false" aria-controls="fixed-sidenav-22-5">Android</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-22-5"><li class="nav-item"><a class="nav-link" href="/platform-integration/android/install-android">Add Android as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/splash-screen">Add a splash screen</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/predictive-back">Add predictive back</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/c-interop">Bind to native code</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/platform-views">Host a native Android view</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/compose-activity">Launch a Jetpack Compose activity</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/restore-state-android">Restore state on Android</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/chromeos">Target ChromeOS with Android</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-22-6" href="/platform-integration/ios" role="button" aria-expanded="false" aria-controls="fixed-sidenav-22-6">iOS</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-22-6"><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/install-ios">Add iOS as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/ios-latest">Flutter on latest iOS</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/apple-frameworks">Leverage Apple's system libraries</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/launch-screen">Add a launch screen</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/ios-app-clip">Add iOS App Clip support</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/app-extensions">Add iOS app extensions</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/c-interop">Bind to native code</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/platform-views">Host a native iOS view</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/ios-debugging">Enable debugging on iOS</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/restore-state-ios">Restore state on iOS</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-22-7" href="/platform-integration/linux" role="button" aria-expanded="false" aria-controls="fixed-sidenav-22-7">Linux</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-22-7"><li class="nav-item"><a class="nav-link" href="/platform-integration/linux/install-linux">Add Linux as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/linux/building">Build a Linux app</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-22-8" href="/platform-integration/macos" role="button" aria-expanded="false" aria-controls="fixed-sidenav-22-8">macOS</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-22-8"><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/install-macos">Add macOS as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/building">Build a macOS app</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/c-interop">Bind to native code</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/platform-views">Host a native macOS view</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-22-9" href="/platform-integration/web" role="button" aria-expanded="false" aria-controls="fixed-sidenav-22-9">Web</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-22-9"><li class="nav-item"><a class="nav-link" href="/platform-integration/web/">Web support in Flutter</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/install-web">Add web as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/building">Build a web app</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/wasm">Compile to WebAssembly</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/initialization">Customize app initialization</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/embedding-flutter-web">Add Flutter to any web app</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/web-content-in-flutter">Web content in Flutter</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/renderers">Web renderers</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/web-images">Display images on the web</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/faq">Web FAQ</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-22-10" href="/platform-integration/windows" role="button" aria-expanded="false" aria-controls="fixed-sidenav-22-10">Windows</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-22-10"><li class="nav-item"><a class="nav-link" href="/platform-integration/windows/install-windows">Add Windows as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/windows/building">Build a Windows app</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link active collapsible" data-toggle="collapse" href="#fixed-sidenav-23" role="button" aria-expanded="true" aria-controls="fixed-sidenav-23">Packages & plugins</a><ul class="nav flex-column flex-nowrap collapse show" id="fixed-sidenav-23"><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/using-packages">Use packages & plugins</a></li><li class="nav-item"><a class="nav-link active" href="/packages-and-plugins/developing-packages">Develop packages & plugins</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-23-3" href="/packages-and-plugins/swift-package-manager" role="button" aria-expanded="false" aria-controls="fixed-sidenav-23-3">Swift Package Manager</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-23-3"><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/swift-package-manager/for-app-developers">For app developers</a></li><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/swift-package-manager/for-plugin-authors">For plugin authors</a></li></ul></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/favorites">Flutter Favorites</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/flutter" target="_blank" rel="noopener">Package repository</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-24" role="button" aria-expanded="false" aria-controls="fixed-sidenav-24">Testing & debugging</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-24"><li class="nav-header">Testing</li><li class="nav-item"><a class="nav-link" href="/testing/overview">Overview</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-24-3" href="#fixed-sidenav-24-3" role="button" aria-expanded="false" aria-controls="fixed-sidenav-24-3">Unit testing</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-24-3"><li class="nav-item"><a class="nav-link" href="/cookbook/testing/unit/introduction">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/unit/mocking">Mock dependencies</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-24-4" href="#fixed-sidenav-24-4" role="button" aria-expanded="false" aria-controls="fixed-sidenav-24-4">Widget testing</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-24-4"><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/introduction">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/finders">Find widgets</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/scrolling">Simulate scrolling</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/tap-drag">Simulate user interaction</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-24-5" href="#fixed-sidenav-24-5" role="button" aria-expanded="false" aria-controls="fixed-sidenav-24-5">Integration testing</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-24-5"><li class="nav-item"><a class="nav-link" href="/cookbook/testing/integration/introduction">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/testing/integration-tests">Write and run an integration test</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/integration/profiling">Profile an integration test</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/testing/testing-plugins">Test a plugin</a></li><li class="nav-item"><a class="nav-link" href="/testing/plugins-in-tests">Handle plugin code in tests</a></li><li class="nav-header">Debugging</li><li class="nav-item"><a class="nav-link" href="/testing/debugging">Debugging tools</a></li><li class="nav-item"><a class="nav-link" href="/testing/code-debugging">Debug your app programmatically</a></li><li class="nav-item"><a class="nav-link" href="/testing/native-debugging">Use a native language debugger</a></li><li class="nav-item"><a class="nav-link" href="/testing/build-modes">Flutter's build modes</a></li><li class="nav-item"><a class="nav-link" href="/testing/common-errors">Common Flutter errors</a></li><li class="nav-item"><a class="nav-link" href="/testing/errors">Handle errors</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/maintenance/error-reporting">Report errors to a service</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-25" role="button" aria-expanded="false" aria-controls="fixed-sidenav-25">Performance & optimization</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-25"><li class="nav-item"><a class="nav-link" href="/perf">Overview</a></li><li class="nav-item"><a class="nav-link" href="/perf/impeller">Impeller</a></li><li class="nav-item"><a class="nav-link" href="/perf/best-practices">Performance best practices</a></li><li class="nav-item"><a class="nav-link" href="/perf/app-size">App size</a></li><li class="nav-item"><a class="nav-link" href="/perf/deferred-components">Deferred components</a></li><li class="nav-item"><a class="nav-link" href="/perf/rendering-performance">Rendering performance</a></li><li class="nav-item"><a class="nav-link" href="/perf/ui-performance">Performance profiling</a></li><li class="nav-item"><a class="nav-link" href="/perf/web-performance">Performance profiling for web</a></li><li class="nav-item"><a class="nav-link" href="/perf/shader">Shader compilation jank</a></li><li class="nav-item"><a class="nav-link" href="/perf/metrics">Performance metrics</a></li><li class="nav-item"><a class="nav-link" href="/perf/isolates">Concurrency and isolates</a></li><li class="nav-item"><a class="nav-link" href="/perf/faq">Performance FAQ</a></li><li class="nav-item"><a class="nav-link" href="/perf/appendix">Appendix</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-26" role="button" aria-expanded="false" aria-controls="fixed-sidenav-26">Deployment</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-26"><li class="nav-item"><a class="nav-link" href="/deployment/obfuscate">Obfuscate Dart code</a></li><li class="nav-item"><a class="nav-link" href="/deployment/flavors">Create flavors of an app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/android">Build and release an Android app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/ios">Build and release an iOS app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/macos">Build and release a macOS app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/linux">Build and release a Linux app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/windows">Build and release a Windows app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/web">Build and release a web app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/cd">Set up continuous deployment</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-27" role="button" aria-expanded="false" aria-controls="fixed-sidenav-27">Add to an existing app</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-27"><li class="nav-item"><a class="nav-link" href="/add-to-app">Introduction</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-27-2" href="/add-to-app/android" role="button" aria-expanded="false" aria-controls="fixed-sidenav-27-2">Add to an Android app</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-27-2"><li class="nav-item"><a class="nav-link" href="/add-to-app/android/project-setup">Set up Android project</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/add-flutter-screen">Add a single Flutter screen</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/add-flutter-fragment">Add a Flutter Fragment</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/add-flutter-view">Add a Flutter View</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/plugin-setup">Use a Flutter plugin</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-27-3" href="/add-to-app/ios" role="button" aria-expanded="false" aria-controls="fixed-sidenav-27-3">Add to an iOS app</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-27-3"><li class="nav-item"><a class="nav-link" href="/add-to-app/ios/project-setup">Set up iOS project</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/ios/add-flutter-screen">Add a single Flutter screen</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/embedding-flutter-web">Add to a web app</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/debugging">Debug embedded Flutter module</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/multiple-flutters">Add multiple Flutter instances</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/performance">Loading sequence and performance</a></li></ul></li><li aria-hidden="true"><div class="sidebar-primary-divider"></div></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-29" role="button" aria-expanded="false" aria-controls="fixed-sidenav-29">Tools & editors</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-29"><li class="nav-item"><a class="nav-link" href="/tools/android-studio">Android Studio & IntelliJ</a></li><li class="nav-item"><a class="nav-link" href="/tools/vs-code">Visual Studio Code</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-29-3" href="/tools/devtools" role="button" aria-expanded="false" aria-controls="fixed-sidenav-29-3">DevTools</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-29-3"><li class="nav-item"><a class="nav-link" href="/tools/devtools">Overview</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/android-studio">Run from Android Studio & IntelliJ</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/vscode">Run from VS Code</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/cli">Run from command line</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/inspector">Flutter inspector</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/performance">Performance view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/cpu-profiler">CPU Profiler view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/memory">Memory view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/console">Debug console view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/network">Network view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/debugger">Debugger</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/logging">Logging view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/app-size">App size tool</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/extensions">DevTools extensions</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/deep-links">Validate deep links</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/release-notes">Release notes</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/tools/sdk">SDK overview</a></li><li class="nav-item"><a class="nav-link" href="/tools/pubspec">Flutter's pubspec options</a></li><li class="nav-item"><a class="nav-link" href="/tools/flutter-fix">Automated fixes</a></li><li class="nav-item"><a class="nav-link" href="/tools/formatting">Code formatting</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-30" role="button" aria-expanded="false" aria-controls="fixed-sidenav-30">Flutter concepts</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-30"><li class="nav-item"><a class="nav-link" href="/resources/architectural-overview">Architectural overview</a></li><li class="nav-item"><a class="nav-link" href="/resources/inside-flutter">Inside Flutter</a></li><li class="nav-item"><a class="nav-link" href="/ui/layout/constraints">Understanding constraints</a></li><li class="nav-item"><a class="nav-link" href="/testing/build-modes">Flutter's build modes</a></li><li class="nav-item"><a class="nav-link" href="/tools/hot-reload">Hot reload</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-31" role="button" aria-expanded="false" aria-controls="fixed-sidenav-31">Resources</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-31"><li class="nav-item"><a class="nav-link" href="/resources/faq">FAQ</a></li><li class="nav-item"><a class="nav-link" href="/resources/books">Books</a></li><li class="nav-item"><a class="nav-link" href="/resources/videos">Videos</a></li><li class="nav-item"><a class="nav-link" href="/resources/courses">Courses</a></li><li class="nav-item"><a class="nav-link" href="/resources/bootstrap-into-dart">Learn Dart</a></li><li class="nav-item"><a class="nav-link" href="/resources/support">Get support</a></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-31-8" href="#fixed-sidenav-31-8" role="button" aria-expanded="false" aria-controls="fixed-sidenav-31-8">Contribute</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-31-8"><li class="nav-item"><a class="nav-link" href="/resources/bug-reports">Create useful bug reports</a></li><li class="nav-item"><a class="nav-link" href="https://github.com/flutter/flutter/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener">Contribute to Flutter</a></li><li class="nav-item"><a class="nav-link" href="/resources/design-docs">Discover proposed features</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-31-9" href="/reference" role="button" aria-expanded="false" aria-controls="fixed-sidenav-31-9">Reference</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-31-9"><li class="nav-item"><a class="nav-link" href="/dash">Who is Dash?</a></li><li class="nav-item"><a class="nav-link" href="/reference/widgets">Widget index</a></li><li class="nav-item"><a class="nav-link" href="/reference/flutter-cli">flutter CLI</a></li><li class="nav-item"><a class="nav-link" href="https://api.flutter.dev" target="_blank" rel="noopener">API docs</a></li></ul></li></ul></li></ul></div><main class="site-content col-12 col-md-9 offset-md-3 col-xl-8 offset-xl-2 col-xxl-8 offset-xxl-2"><div id="site-toc--side" class="site-toc fixed-col col-xl-2 order-3" data-fixed-column><header class="site-toc__title">Contents</header><ul class="section-nav"><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#package-introduction">Package introduction</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#types">Package types</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#dart">Developing Dart packages</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#step-1-create-the-package">Step 1: Create the package</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#step-2-implement-the-package">Step 2: Implement the package</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#plugin">Developing plugin packages</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#federated-plugins">Federated plugins</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#plugin-platforms">Specifying a plugin's supported platforms</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#step-1-create-the-package-1">Step 1: Create the package</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#edit-plugin-package">Step 2: Implement the package</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#add-support-for-platforms-in-an-existing-plugin-project">Add support for platforms in an existing plugin project</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#dart-platform-implementations">Dart platform implementations</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#testing-your-plugin">Testing your plugin</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#plugin-ffi">Developing FFI plugin packages</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#step-1-create-the-package-2">Step 1: Create the package</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#step-2-building-and-bundling-native-code">Step 2: Building and bundling native code</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#step-3-binding-to-native-code">Step 3: Binding to native code</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#step-4-invoking-native-code">Step 4: Invoking native code</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#adding-documentation">Adding documentation</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#api-documentation">API documentation</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#adding-licenses-to-the-license-file">Adding licenses to the LICENSE file</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#publish">Publishing your package</a></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#dependencies">Handling package interdependencies</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#android">Android</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#ios">iOS</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#web">Web</a></li></ul></li></ul></div><div class="container"><header class="site-content__title" id="site-content-title"><h1>Developing packages & plugins</h1><nav class="breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb-list" vocab="https://schema.org/" typeof="BreadcrumbList"><li class="breadcrumb-item" property="itemListElement" typeof="ListItem"><a href="/packages-and-plugins" property="item" typeof="WebPage"><span property="name">Packages & plugins</span></a><meta property="position" content="0"><span class="material-symbols-outlined child-icon" aria-hidden="true">chevron_right</span></li><li class="breadcrumb-item active" property="itemListElement" typeof="ListItem" aria-current="page"><a href="/packages-and-plugins/developing-packages" property="item" typeof="WebPage"><span property="name">Developing</span></a><meta property="position" content="1"></li></ol></nav></header><div id="site-toc--inline" class="site-toc toc-collapsible toc-collapsed"><header class="site-toc__title">Contents <span class="site-toc--inline__toggle toc-toggle-down" title="Expand table of contents"><i class="material-symbols" aria-hidden="true">keyboard_arrow_down</i></span> <span class="site-toc--inline__toggle toc-toggle-up" title="Collapse table of contents"><i class="material-symbols" aria-hidden="true">keyboard_arrow_up</i></span></header><ul class="section-nav"><li class="toc-entry toc-h2"><a href="#package-introduction">Package introduction</a><ul><li class="toc-entry toc-h3"><a href="#types">Package types</a></li></ul></li><li class="toc-entry toc-h2"><a href="#dart">Developing Dart packages</a><ul><li class="toc-entry toc-h3"><a href="#step-1-create-the-package">Step 1: Create the package</a></li><li class="toc-entry toc-h3"><a href="#step-2-implement-the-package">Step 2: Implement the package</a></li></ul></li><li class="toc-entry toc-h2"><a href="#plugin">Developing plugin packages</a><ul><li class="toc-entry toc-h3"><a href="#federated-plugins">Federated plugins</a></li><li class="toc-entry toc-h3"><a href="#plugin-platforms">Specifying a plugin's supported platforms</a></li><li class="toc-entry toc-h3"><a href="#step-1-create-the-package-1">Step 1: Create the package</a></li><li class="toc-entry toc-h3"><a href="#edit-plugin-package">Step 2: Implement the package</a></li><li class="toc-entry toc-h3"><a href="#add-support-for-platforms-in-an-existing-plugin-project">Add support for platforms in an existing plugin project</a></li><li class="toc-entry toc-h3"><a href="#dart-platform-implementations">Dart platform implementations</a></li><li class="toc-entry toc-h3"><a href="#testing-your-plugin">Testing your plugin</a></li></ul></li><li class="toc-entry toc-h2"><a href="#plugin-ffi">Developing FFI plugin packages</a><ul><li class="toc-entry toc-h3"><a href="#step-1-create-the-package-2">Step 1: Create the package</a></li><li class="toc-entry toc-h3"><a href="#step-2-building-and-bundling-native-code">Step 2: Building and bundling native code</a></li><li class="toc-entry toc-h3"><a href="#step-3-binding-to-native-code">Step 3: Binding to native code</a></li><li class="toc-entry toc-h3"><a href="#step-4-invoking-native-code">Step 4: Invoking native code</a></li></ul></li><li class="toc-entry toc-h2"><a href="#adding-documentation">Adding documentation</a><ul><li class="toc-entry toc-h3"><a href="#api-documentation">API documentation</a></li><li class="toc-entry toc-h3"><a href="#adding-licenses-to-the-license-file">Adding licenses to the LICENSE file</a></li></ul></li><li class="toc-entry toc-h2"><a href="#publish">Publishing your package</a></li><li class="toc-entry toc-h2"><a href="#dependencies">Handling package interdependencies</a><ul><li class="toc-entry toc-h3"><a href="#android">Android</a></li><li class="toc-entry toc-h3"><a href="#ios">iOS</a></li><li class="toc-entry toc-h3"><a href="#web">Web</a></li></ul></li></ul><span class="site-toc--inline__toggle toc-toggle-more-items" title="Expand table of contents"><i class="material-symbols" aria-hidden="true">more_horiz</i></span></div><div class="header-wrapper"><h2 id="package-introduction">Package introduction</h2><a class="heading-link" href="#package-introduction" aria-label="Link to 'Package introduction' section">#</a></div><p>Packages enable the creation of modular code that can be shared easily. A minimal package consists of the following:</p><dl><dt><strong><code>pubspec.yaml</code></strong></dt><dd>A metadata file that declares the package name, version, author, and so on.</dd><dt><strong><code>lib</code></strong></dt><dd>The <code>lib</code> directory contains the public code in the package, minimally a single <code>&lt;package-name&gt;.dart</code> file.</dd></dl><aside class="alert alert-info"><div class="alert-header"><i class="material-symbols" aria-hidden="true">info</i> <span>Note</span></div><div class="alert-content"><p>For a list of dos and don'ts when writing an effective plugin, see the Medium article by Mehmet Fidanboylu, <a href="https://medium.com/flutter/writing-a-good-flutter-plugin-1a561b986c9c">Writing a good plugin</a>.</p></div></aside><div class="header-wrapper"><h3 id="types">Package types</h3><a class="heading-link" href="#types" aria-label="Link to 'Package types' section">#</a></div><p>Packages can contain more than one kind of content:</p><dl><dt><strong>Dart packages</strong></dt><dd><p>General packages written in Dart, for example the <a href="https://pub.dev/packages/path"><code>path</code></a> package. Some of these might contain Flutter specific functionality and thus have a dependency on the Flutter framework, restricting their use to Flutter only, for example the <a href="https://pub.dev/packages/fluro"><code>fluro</code></a> package.</p></dd><dt><strong>Plugin packages</strong></dt><dd><p>A specialized Dart package that contains an API written in Dart code combined with one or more platform-specific implementations.</p><p>Plugin packages can be written for Android (using Kotlin or Java), iOS (using Swift or Objective-C), web, macOS, Windows, or Linux, or any combination thereof.</p><p>A concrete example is the <a href="https://pub.dev/packages/url_launcher"><code>url_launcher</code></a> plugin package. To see how to use the <code>url_launcher</code> package, and how it was extended to implement support for web, see the Medium article by Harry Terkelsen, <a href="https://medium.com/flutter/how-to-write-a-flutter-web-plugin-5e26c689ea1">How to Write a Flutter Web Plugin, Part 1</a>.</p></dd><dt><strong>FFI Plugin packages</strong></dt><dd><p>A specialized Dart package that contains an API written in Dart code combined with one or more platform-specific implementations that use Dart FFI(<a href="/platform-integration/android/c-interop">Android</a>, <a href="/platform-integration/ios/c-interop">iOS</a>, <a href="/platform-integration/macos/c-interop">macOS</a>).</p></dd></dl><div class="header-wrapper"><h2 id="dart">Developing Dart packages</h2><a class="heading-link" href="#dart" aria-label="Link to 'Developing Dart packages' section">#</a></div><p>The following instructions explain how to write a Flutter package.</p><div class="header-wrapper"><h3 id="step-1-create-the-package">Step 1: Create the package</h3><a class="heading-link" href="#step-1-create-the-package" aria-label="Link to 'Step 1: Create the package' section">#</a></div><p>To create a starter Flutter package, use the <code>--template=package</code> flag with <code>flutter create</code>:</p><div class="code-block-wrapper language-console"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222" class="undefined terminal-command">flutter create --template=</span><span style="color:#0C7064">package</span><span style="color:#6200EE"> hello</span></span></code></pre></div></div><p>This creates a package project in the <code>hello</code> folder with the following content:</p><dl><dt><strong>LICENSE</strong></dt><dd>A (mostly) empty license text file.</dd><dt><strong>test/hello_test.dart</strong></dt><dd>The <a href="/testing/overview#unit-tests">unit tests</a> for the package.</dd><dt><strong>hello.iml</strong></dt><dd>A configuration file used by the IntelliJ IDEs.</dd><dt><strong>.gitignore</strong></dt><dd>A hidden file that tells Git which files or folders to ignore in a project.</dd><dt><strong>.metadata</strong></dt><dd>A hidden file used by IDEs to track the properties of the Flutter project.</dd><dt><strong>pubspec.yaml</strong></dt><dd>A yaml file containing metadata that specifies the package's dependencies. Used by the pub tool.</dd><dt><strong>README.md</strong></dt><dd>A starter markdown file that briefly describes the package's purpose.</dd><dt><strong>lib/hello.dart</strong></dt><dd>A starter app containing Dart code for the package.</dd><dt><strong>.idea/modules.xml</strong>, <strong>.idea/workspace.xml</strong></dt><dd>A hidden folder containing configuration files for the IntelliJ IDEs.</dd><dt><strong>CHANGELOG.md</strong></dt><dd>A (mostly) empty markdown file for tracking version changes to the package.</dd></dl><div class="header-wrapper"><h3 id="step-2-implement-the-package">Step 2: Implement the package</h3><a class="heading-link" href="#step-2-implement-the-package" aria-label="Link to 'Step 2: Implement the package' section">#</a></div><p>For pure Dart packages, simply add the functionality inside the main <code>lib/&lt;package name&gt;.dart</code> file, or in several files in the <code>lib</code> directory.</p><p>To test the package, add <a href="/testing/overview#unit-tests">unit tests</a> in a <code>test</code> directory.</p><p>For additional details on how to organize the package contents, see the <a href="https://dart.dev/guides/libraries/create-library-packages">Dart library package</a> documentation.</p><div class="header-wrapper"><h2 id="plugin">Developing plugin packages</h2><a class="heading-link" href="#plugin" aria-label="Link to 'Developing plugin packages' section">#</a></div><p>If you want to develop a package that calls into platform-specific APIs, you need to develop a plugin package.</p><p>The API is connected to the platform-specific implementation(s) using a <a href="/platform-integration/platform-channels">platform channel</a>.</p><div class="header-wrapper"><h3 id="federated-plugins">Federated plugins</h3><a class="heading-link" href="#federated-plugins" aria-label="Link to 'Federated plugins' section">#</a></div><p>Federated plugins are a way of splitting support for different platforms into separate packages. So, a federated plugin can use one package for iOS, another for Android, another for web, and yet another for a car (as an example of an IoT device). Among other benefits, this approach allows a domain expert to extend an existing plugin to work for the platform they know best.</p><p>A federated plugin requires the following packages:</p><dl><dt><strong>app-facing package</strong></dt><dd>The package that plugin users depend on to use the plugin. This package specifies the API used by the Flutter app.</dd><dt><strong>platform package(s)</strong></dt><dd>One or more packages that contain the platform-specific implementation code. The app-facing package calls into these packages—they aren't included into an app, unless they contain platform-specific functionality accessible to the end user.</dd><dt><strong>platform interface package</strong></dt><dd>The package that glues the app-facing package to the platform package(s). This package declares an interface that any platform package must implement to support the app-facing package. Having a single package that defines this interface ensures that all platform packages implement the same functionality in a uniform way.</dd></dl><div class="header-wrapper"><h4 id="endorsed-federated-plugin">Endorsed federated plugin</h4><a class="heading-link" href="#endorsed-federated-plugin" aria-label="Link to 'Endorsed federated plugin' section">#</a></div><p>Ideally, when adding a platform implementation to a federated plugin, you will coordinate with the package author to include your implementation. In this way, the original author <em>endorses</em> your implementation.</p><p>For example, say you write a <code>foobar_windows</code> implementation for the (imaginary) <code>foobar</code> plugin. In an endorsed plugin, the original <code>foobar</code> author adds your Windows implementation as a dependency in the pubspec for the app-facing package. Then, when a developer includes the <code>foobar</code> plugin in their Flutter app, the Windows implementation, as well as the other endorsed implementations, are automatically available to the app.</p><div class="header-wrapper"><h4 id="non-endorsed-federated-plugin">Non-endorsed federated plugin</h4><a class="heading-link" href="#non-endorsed-federated-plugin" aria-label="Link to 'Non-endorsed federated plugin' section">#</a></div><p>If you can't, for whatever reason, get your implementation added by the original plugin author, then your plugin is <em>not</em> endorsed. A developer can still use your implementation, but must manually add the plugin to the app's pubspec file. So, the developer must include both the <code>foobar</code> dependency <em>and</em> the <code>foobar_windows</code> dependency in order to achieve full functionality.</p><p>For more information on federated plugins, why they are useful, and how they are implemented, see the Medium article by Harry Terkelsen, <a href="https://medium.com/flutter/how-to-write-a-flutter-web-plugin-part-2-afdddb69ece6">How To Write a Flutter Web Plugin, Part 2</a>.</p><div class="header-wrapper"><h3 id="plugin-platforms">Specifying a plugin's supported platforms</h3><a class="heading-link" href="#plugin-platforms" aria-label="Link to 'Specifying a plugin's supported platforms' section">#</a></div><p>Plugins can specify the platforms they support by adding keys to the <code>platforms</code> map in the <code>pubspec.yaml</code> file. For example, the following pubspec file shows the <code>flutter:</code> map for the <code>hello</code> plugin, which supports only iOS and Android:</p><div class="code-block-wrapper language-yaml"><div class="code-block-body"><span class="code-block-language" title="Language yaml">yaml</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">flutter</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> plugin</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> platforms</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> android</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> package</span><span style="color:#222222">: </span><span style="color:#0C7064">com.example.hello</span></span> <span class="line"><span style="color:#0468D7"> pluginClass</span><span style="color:#222222">: </span><span style="color:#0C7064">HelloPlugin</span></span> <span class="line"><span style="color:#0468D7"> ios</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> pluginClass</span><span style="color:#222222">: </span><span style="color:#0C7064">HelloPlugin</span></span></code></pre></div></div><p>When adding plugin implementations for more platforms, the <code>platforms</code> map should be updated accordingly. For example, here's the map in the pubspec file for the <code>hello</code> plugin, when updated to add support for macOS and web:</p><div class="code-block-wrapper language-yaml"><div class="code-block-body"><span class="code-block-language" title="Language yaml">yaml</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">flutter</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> plugin</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> platforms</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> android</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> package</span><span style="color:#222222">: </span><span style="color:#0C7064">com.example.hello</span></span> <span class="line"><span style="color:#0468D7"> pluginClass</span><span style="color:#222222">: </span><span style="color:#0C7064">HelloPlugin</span></span> <span class="line"><span style="color:#0468D7"> ios</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> pluginClass</span><span style="color:#222222">: </span><span style="color:#0C7064">HelloPlugin</span></span> <span class="line"><span style="color:#0468D7"> macos</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> pluginClass</span><span style="color:#222222">: </span><span style="color:#0C7064">HelloPlugin</span></span> <span class="line"><span style="color:#0468D7"> web</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> pluginClass</span><span style="color:#222222">: </span><span style="color:#0C7064">HelloPlugin</span></span> <span class="line"><span style="color:#0468D7"> fileName</span><span style="color:#222222">: </span><span style="color:#0C7064">hello_web.dart</span></span></code></pre></div></div><div class="header-wrapper"><h4 id="federated-platform-packages">Federated platform packages</h4><a class="heading-link" href="#federated-platform-packages" aria-label="Link to 'Federated platform packages' section">#</a></div><p>A platform package uses the same format, but includes an <code>implements</code> entry indicating which app-facing package it implements. For example, a <code>hello_windows</code> plugin containing the Windows implementation for <code>hello</code> would have the following <code>flutter:</code> map:</p><div class="code-block-wrapper language-yaml"><div class="code-block-body"><span class="code-block-language" title="Language yaml">yaml</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">flutter</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> plugin</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> implements</span><span style="color:#222222">: </span><span style="color:#0C7064">hello</span></span> <span class="line"><span style="color:#0468D7"> platforms</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> windows</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> pluginClass</span><span style="color:#222222">: </span><span style="color:#0C7064">HelloPlugin</span></span></code></pre></div></div><div class="header-wrapper"><h4 id="endorsed-implementations">Endorsed implementations</h4><a class="heading-link" href="#endorsed-implementations" aria-label="Link to 'Endorsed implementations' section">#</a></div><p>An app facing package can endorse a platform package by adding a dependency on it, and including it as a <code>default_package</code> in the <code>platforms:</code> map. If the <code>hello</code> plugin above endorsed <code>hello_windows</code>, it would look as follows:</p><div class="code-block-wrapper language-yaml"><div class="code-block-body"><span class="code-block-language" title="Language yaml">yaml</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">flutter</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> plugin</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> platforms</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> android</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> package</span><span style="color:#222222">: </span><span style="color:#0C7064">com.example.hello</span></span> <span class="line"><span style="color:#0468D7"> pluginClass</span><span style="color:#222222">: </span><span style="color:#0C7064">HelloPlugin</span></span> <span class="line"><span style="color:#0468D7"> ios</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> pluginClass</span><span style="color:#222222">: </span><span style="color:#0C7064">HelloPlugin</span></span> <span class="line"><span style="color:#0468D7"> windows</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> default_package</span><span style="color:#222222">: </span><span style="color:#0C7064">hello_windows</span></span> <span class="line"></span> <span class="line"><span style="color:#0468D7">dependencies</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> hello_windows</span><span style="color:#222222">: </span><span style="color:#0C7064">^1.0.0</span></span></code></pre></div></div><p>Note that as shown here, an app-facing package can have some platforms implemented within the package, and others in endorsed federated implementations.</p><div class="header-wrapper"><h4 id="shared-ios-and-macos-implementations">Shared iOS and macOS implementations</h4><a class="heading-link" href="#shared-ios-and-macos-implementations" aria-label="Link to 'Shared iOS and macOS implementations' section">#</a></div><p>Many frameworks support both iOS and macOS with identical or mostly identical APIs, making it possible to implement some plugins for both iOS and macOS with the same codebase. Normally each platform's implementation is in its own folder, but the <code>sharedDarwinSource</code> option allows iOS and macOS to use the same folder instead:</p><div class="code-block-wrapper language-yaml"><div class="code-block-body"><span class="code-block-language" title="Language yaml">yaml</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">flutter</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> plugin</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> platforms</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> ios</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> pluginClass</span><span style="color:#222222">: </span><span style="color:#0C7064">HelloPlugin</span></span> <span class="line"><span style="color:#0468D7"> sharedDarwinSource</span><span style="color:#222222">: </span><span style="color:#0C7064">true</span></span> <span class="line"><span style="color:#0468D7"> macos</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> pluginClass</span><span style="color:#222222">: </span><span style="color:#0C7064">HelloPlugin</span></span> <span class="line"><span style="color:#0468D7"> sharedDarwinSource</span><span style="color:#222222">: </span><span style="color:#0C7064">true</span></span> <span class="line"></span> <span class="line"><span style="color:#0468D7">environment</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> sdk</span><span style="color:#222222">: </span><span style="color:#0C7064">^3.0.0</span></span> <span class="line"><span style="color:#6E6E70"> # Flutter versions prior to 3.7 did not support the</span></span> <span class="line"><span style="color:#6E6E70"> # sharedDarwinSource option.</span></span> <span class="line"><span style="color:#0468D7"> flutter</span><span style="color:#222222">: </span><span style="color:#0C7064">">=3.7.0"</span></span></code></pre></div></div><p>When <code>sharedDarwinSource</code> is enabled, instead of an <code>ios</code> directory for iOS and a <code>macos</code> directory for macOS, both platforms use a shared <code>darwin</code> directory for all code and resources. When enabling this option, you need to move any existing files from <code>ios</code> and <code>macos</code> to the shared directory. You also need to update the podspec file to set the dependencies and deployment targets for both platforms, for example:</p><div class="code-block-wrapper language-ruby"><div class="code-block-body"><span class="code-block-language" title="Language ruby">ruby</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222"> s.ios.dependency </span><span style="color:#0C7064">'Flutter'</span></span> <span class="line"><span style="color:#222222"> s.osx.dependency </span><span style="color:#0C7064">'FlutterMacOS'</span></span> <span class="line"><span style="color:#222222"> s.ios.deployment_target = </span><span style="color:#0C7064">'11.0'</span></span> <span class="line"><span style="color:#222222"> s.osx.deployment_target = </span><span style="color:#0C7064">'10.14'</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="step-1-create-the-package-1">Step 1: Create the package</h3><a class="heading-link" href="#step-1-create-the-package-1" aria-label="Link to 'Step 1: Create the package' section">#</a></div><p>To create a plugin package, use the <code>--template=plugin</code> flag with <code>flutter create</code>.</p><p>Use the <code>--platforms=</code> option followed by a comma-separated list to specify the platforms that the plugin supports. Available platforms are: <code>android</code>, <code>ios</code>, <code>web</code>, <code>linux</code>, <code>macos</code>, and <code>windows</code>. If no platforms are specified, the resulting project doesn't support any platforms.</p><p>Use the <code>--org</code> option to specify your organization, using reverse domain name notation. This value is used in various package and bundle identifiers in the generated plugin code.</p><p>By default, the plugin project uses Swift for iOS code and Kotlin for Android code. If you prefer Objective-C or Java, you can specify the iOS language using <code>-i</code> and the Android language using <code>-a</code>. Please choose <strong>one</strong> of the following:</p><div class="code-block-wrapper language-console"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222" class="undefined terminal-command">flutter create --org com.example --template=</span><span style="color:#0C7064">plugin</span><span style="color:#222222"> --platforms=</span><span style="color:#0C7064">android,ios,linux,macos,windows</span><span style="color:#6200EE"> -a</span><span style="color:#0C7064"> kotlin</span><span style="color:#0C7064"> hello</span></span></code></pre></div></div><div class="code-block-wrapper language-console"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222" class="undefined terminal-command">flutter create --org com.example --template=</span><span style="color:#0C7064">plugin</span><span style="color:#222222"> --platforms=</span><span style="color:#0C7064">android,ios,linux,macos,windows</span><span style="color:#6200EE"> -a</span><span style="color:#0C7064"> java</span><span style="color:#0C7064"> hello</span></span></code></pre></div></div><div class="code-block-wrapper language-console"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222" class="undefined terminal-command">flutter create --org com.example --template=</span><span style="color:#0C7064">plugin</span><span style="color:#222222"> --platforms=</span><span style="color:#0C7064">android,ios,linux,macos,windows</span><span style="color:#6200EE"> -i</span><span style="color:#0C7064"> objc</span><span style="color:#0C7064"> hello</span></span></code></pre></div></div><div class="code-block-wrapper language-console"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222" class="undefined terminal-command">flutter create --org com.example --template=</span><span style="color:#0C7064">plugin</span><span style="color:#222222"> --platforms=</span><span style="color:#0C7064">android,ios,linux,macos,windows</span><span style="color:#6200EE"> -i</span><span style="color:#0C7064"> swift</span><span style="color:#0C7064"> hello</span></span></code></pre></div></div><p>This creates a plugin project in the <code>hello</code> folder with the following specialized content:</p><dl><dt><strong><code>lib/hello.dart</code></strong></dt><dd>The Dart API for the plugin.</dd><dt><strong><code>android/src/main/java/com/example/hello/HelloPlugin.kt</code></strong></dt><dd>The Android platform-specific implementation of the plugin API in Kotlin.</dd><dt><strong><code>ios/Classes/HelloPlugin.m</code></strong></dt><dd>The iOS-platform specific implementation of the plugin API in Objective-C.</dd><dt><strong><code>example/</code></strong></dt><dd>A Flutter app that depends on the plugin, and illustrates how to use it.</dd></dl><div class="header-wrapper"><h3 id="edit-plugin-package">Step 2: Implement the package</h3><a class="heading-link" href="#edit-plugin-package" aria-label="Link to 'Step 2: Implement the package' section">#</a></div><p>As a plugin package contains code for several platforms written in several programming languages, some specific steps are needed to ensure a smooth experience.</p><div class="header-wrapper"><h4 id="step-2a-define-the-package-api-dart">Step 2a: Define the package API (.dart)</h4><a class="heading-link" href="#step-2a-define-the-package-api-dart" aria-label="Link to 'Step 2a: Define the package API (.dart)' section">#</a></div><p>The API of the plugin package is defined in Dart code. Open the main <code>hello/</code> folder in your favorite <a href="/get-started/editor">Flutter editor</a>. Locate the file <code>lib/hello.dart</code>.</p><div class="header-wrapper"><h4 id="step-2b-add-android-platform-code-kt-java">Step 2b: Add Android platform code (.kt/.java)</h4><a class="heading-link" href="#step-2b-add-android-platform-code-kt-java" aria-label="Link to 'Step 2b: Add Android platform code (.kt/.java)' section">#</a></div><p>We recommend you edit the Android code using Android Studio.</p><p>Before editing the Android platform code in Android Studio, first make sure that the code has been built at least once (in other words, run the example app from your IDE/editor, or in a terminal execute <code>cd hello/example; flutter build apk --config-only</code>).</p><p>Then use the following steps:</p><ol><li>Launch Android Studio.</li><li>Select <strong>Open an existing Android Studio Project</strong> in the <strong>Welcome to Android Studio</strong> dialog, or select <strong>File &gt; Open</strong> from the menu, and select the <code>hello/example/android/build.gradle</code> file.</li><li>In the <strong>Gradle Sync</strong> dialog, select <strong>OK</strong>.</li><li>In the <strong>Android Gradle Plugin Update</strong> dialog, select <strong>Don't remind me again for this project</strong>.</li></ol><p>The Android platform code of your plugin is located in <code>hello/java/com.example.hello/HelloPlugin</code>.</p><p>You can run the example app from Android Studio by pressing the run (▶) button.</p><div class="header-wrapper"><h4 id="step-2c-add-ios-platform-code-swift-hplus-m">Step 2c: Add iOS platform code (.swift/.h+.m)</h4><a class="heading-link" href="#step-2c-add-ios-platform-code-swift-hplus-m" aria-label="Link to 'Step 2c: Add iOS platform code (.swift/.h+.m)' section">#</a></div><p>We recommend you edit the iOS code using Xcode.</p><p>Before editing the iOS platform code in Xcode, first make sure that the code has been built at least once (in other words, run the example app from your IDE/editor, or in a terminal execute <code>cd hello/example; flutter build ios --no-codesign --config-only</code>).</p><p>Then use the following steps:</p><ol><li>Launch Xcode.</li><li>Select <strong>File &gt; Open</strong>, and select the <code>hello/example/ios/Runner.xcworkspace</code> file.</li></ol><p>The iOS platform code for your plugin is located in <code>Pods/Development Pods/hello/../../example/ios/.symlinks/plugins/hello/ios/Classes</code> in the Project Navigator. (If you are using <code>sharedDarwinSource</code>, the path will end with <code>hello/darwin/Classes</code> instead.)</p><p>You can run the example app by pressing the run (▶) button.</p><div class="header-wrapper"><h5 id="add-cocoapod-dependencies">Add CocoaPod dependencies</h5><a class="heading-link" href="#add-cocoapod-dependencies" aria-label="Link to 'Add CocoaPod dependencies' section">#</a></div><aside class="alert alert-warning"><div class="alert-header"><i class="material-symbols" aria-hidden="true">warning</i> <span>Warning</span></div><div class="alert-content"><p>Flutter is migrating to <a href="https://www.swift.org/documentation/package-manager/">Swift Package Manager</a> to manage iOS and macOS native dependencies. Flutter's support of Swift Package Manager is under development. The implementation might change in the future. Swift Package Manager support is only available on Flutter's <a href="/release/upgrade#switching-flutter-channels"><code>main</code> channel</a>. Flutter continues to support CocoaPods.</p></div></aside><p>Use the following instructions to add <code>HelloPod</code> with the version <code>0.0.1</code>:</p><ol><li><p>Specify the dependency at the end of <code>ios/hello.podspec</code>:</p><div class="code-block-wrapper language-ruby"><div class="code-block-body"><span class="code-block-language" title="Language ruby">ruby</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222">s.dependency </span><span style="color:#0C7064">'HelloPod'</span><span style="color:#222222">, </span><span style="color:#0C7064">'0.0.1'</span></span></code></pre></div></div><p>For private pods, refer to <a href="https://guides.cocoapods.org/making/private-cocoapods.html">Private CocoaPods</a> to ensure repo access:</p><div class="code-block-wrapper language-ruby"><div class="code-block-body"><span class="code-block-language" title="Language ruby">ruby</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222">s.source = {</span></span> <span class="line"><span style="color:#6E6E70"> # For pods hosted on GitHub</span></span> <span class="line"><span style="color:#222222"> :</span><span style="color:#0C7064">git</span><span style="color:#222222"> => </span><span style="color:#0C7064">"https://github.com/path/to/HelloPod.git"</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#6E6E70"> # Alternatively, for pods hosted locally</span></span> <span class="line"><span style="color:#6E6E70"> # :path => "file:///path/to/private/repo",</span></span> <span class="line"><span style="color:#222222"> :</span><span style="color:#0C7064">tag</span><span style="color:#222222"> => s.version.to_s</span></span> <span class="line"><span style="color:#222222"> }</span><span style="color:#0C7064">`</span></span></code></pre></div></div></li></ol><ol start="2"><li><p>Installing the plugin</p><ul><li>Add the plugin in the project’s <code>pubspec.yaml</code> dependencies.</li><li>Run <code>flutter pub get</code>.</li><li>In the project’s <code>ios/</code> directory, run <code>pod install</code>.</li></ul></li></ol><p>The pod should appear in the installation summary.</p><p>If your plugin requires a privacy manifest, for example, if it uses any <strong>required reason APIs</strong>, update the <code>PrivacyInfo.xcprivacy</code> file to describe your plugin's privacy impact, and add the following to the bottom of your podspec file:</p><div class="code-block-wrapper language-ruby"><div class="code-block-body"><span class="code-block-language" title="Language ruby">ruby</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222">s.resource_bundles = {</span><span style="color:#0C7064">'your_plugin_privacy'</span><span style="color:#222222"> => [</span><span style="color:#0C7064">'your_plugin/Sources/your_plugin/Resources/PrivacyInfo.xcprivacy'</span><span style="color:#222222">]}</span></span></code></pre></div></div><p>For more information, check out <a href="https://developer.apple.com/documentation/bundleresources/privacy_manifest_files">Privacy manifest files</a> on the Apple developer site.</p><div class="header-wrapper"><h4 id="step-2d-add-linux-platform-code-hplus-cc">Step 2d: Add Linux platform code (.h+.cc)</h4><a class="heading-link" href="#step-2d-add-linux-platform-code-hplus-cc" aria-label="Link to 'Step 2d: Add Linux platform code (.h+.cc)' section">#</a></div><p>We recommend you edit the Linux code using an IDE with C++ integration. The instructions below are for Visual Studio Code with the &quot;C/C++&quot; and &quot;CMake&quot; extensions installed, but can be adjusted for other IDEs.</p><p>Before editing the Linux platform code in an IDE, first make sure that the code has been built at least once (in other words, run the example app from your Flutter IDE/editor, or in a terminal execute <code>cd hello/example; flutter build linux</code>).</p><p>Then use the following steps:</p><ol><li>Launch Visual Studio Code.</li><li>Open the <code>hello/example/linux/</code> directory.</li><li>Choose <strong>Yes</strong> in the prompt asking: <code>Would you like to configure project &quot;linux&quot;?</code>. This will allow C++ autocomplete to work.</li></ol><p>The Linux platform code for your plugin is located in <code>flutter/ephemeral/.plugin_symlinks/hello/linux/</code>.</p><p>You can run the example app using <code>flutter run</code>. <strong>Note:</strong> Creating a runnable Flutter application on Linux requires steps that are part of the <code>flutter</code> tool, so even if your editor provides CMake integration building and running that way won't work correctly.</p><div class="header-wrapper"><h4 id="step-2e-add-macos-platform-code-swift">Step 2e: Add macOS platform code (.swift)</h4><a class="heading-link" href="#step-2e-add-macos-platform-code-swift" aria-label="Link to 'Step 2e: Add macOS platform code (.swift)' section">#</a></div><p>We recommend you edit the macOS code using Xcode.</p><p>Before editing the macOS platform code in Xcode, first make sure that the code has been built at least once (in other words, run the example app from your IDE/editor, or in a terminal execute <code>cd hello/example; flutter build macos --config-only</code>).</p><p>Then use the following steps:</p><ol><li>Launch Xcode.</li><li>Select <strong>File &gt; Open</strong>, and select the <code>hello/example/macos/Runner.xcworkspace</code> file.</li></ol><p>The macOS platform code for your plugin is located in <code>Pods/Development Pods/hello/../../example/macos/Flutter/ephemeral/.symlinks/plugins/hello/macos/Classes</code> in the Project Navigator. (If you are using <code>sharedDarwinSource</code>, the path will end with <code>hello/darwin/Classes</code> instead.)</p><p>You can run the example app by pressing the run (▶) button.</p><div class="header-wrapper"><h4 id="step-2f-add-windows-platform-code-hplus-cpp">Step 2f: Add Windows platform code (.h+.cpp)</h4><a class="heading-link" href="#step-2f-add-windows-platform-code-hplus-cpp" aria-label="Link to 'Step 2f: Add Windows platform code (.h+.cpp)' section">#</a></div><p>We recommend you edit the Windows code using Visual Studio.</p><p>Before editing the Windows platform code in Visual Studio, first make sure that the code has been built at least once (in other words, run the example app from your IDE/editor, or in a terminal execute <code>cd hello/example; flutter build windows</code>).</p><p>Then use the following steps:</p><ol><li>Launch Visual Studio.</li><li>Select <strong>Open a project or solution</strong>, and select the <code>hello/example/build/windows/hello_example.sln</code> file.</li></ol><p>The Windows platform code for your plugin is located in <code>hello_plugin/Source Files</code> and <code>hello_plugin/Header Files</code> in the Solution Explorer.</p><p>You can run the example app by right-clicking <code>hello_example</code> in the Solution Explorer and selecting <strong>Set as Startup Project</strong>, then pressing the run (▶) button. <strong>Important:</strong> After making changes to plugin code, you must select <strong>Build &gt; Build Solution</strong> before running again, otherwise an outdated copy of the built plugin will be run instead of the latest version containing your changes.</p><div class="header-wrapper"><h4 id="step-2g-connect-the-api-and-the-platform-code">Step 2g: Connect the API and the platform code</h4><a class="heading-link" href="#step-2g-connect-the-api-and-the-platform-code" aria-label="Link to 'Step 2g: Connect the API and the platform code' section">#</a></div><p>Finally, you need to connect the API written in Dart code with the platform-specific implementations. This is done using a <a href="/platform-integration/platform-channels">platform channel</a>, or through the interfaces defined in a platform interface package.</p><div class="header-wrapper"><h3 id="add-support-for-platforms-in-an-existing-plugin-project">Add support for platforms in an existing plugin project</h3><a class="heading-link" href="#add-support-for-platforms-in-an-existing-plugin-project" aria-label="Link to 'Add support for platforms in an existing plugin project' section">#</a></div><p>To add support for specific platforms to an existing plugin project, run <code>flutter create</code> with the <code>--template=plugin</code> flag again in the project directory. For example, to add web support in an existing plugin, run:</p><div class="code-block-wrapper language-console"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222" class="undefined terminal-command">flutter create --template=</span><span style="color:#0C7064">plugin</span><span style="color:#222222"> --platforms=</span><span style="color:#0C7064">web</span><span style="color:#6200EE"> .</span></span></code></pre></div></div><p>If this command displays a message about updating the <code>pubspec.yaml</code> file, follow the provided instructions.</p><div class="header-wrapper"><h3 id="dart-platform-implementations">Dart platform implementations</h3><a class="heading-link" href="#dart-platform-implementations" aria-label="Link to 'Dart platform implementations' section">#</a></div><p>In many cases, non-web platform implementations only use the platform-specific implementation language, as shown above. However, platform implementations can also use platform-specific Dart as well.</p><aside class="alert alert-info"><div class="alert-header"><i class="material-symbols" aria-hidden="true">info</i> <span>Note</span></div><div class="alert-content"><p>The examples below only apply to non-web platforms. Web plugin implementations are always written in Dart, and use <code>pluginClass</code> and <code>fileName</code> for their Dart implementations as shown above.</p></div></aside><div class="header-wrapper"><h4 id="dart-only-platform-implementations">Dart-only platform implementations</h4><a class="heading-link" href="#dart-only-platform-implementations" aria-label="Link to 'Dart-only platform implementations' section">#</a></div><p>In some cases, some platforms can be implemented entirely in Dart (for example, using FFI). For a Dart-only platform implementation on a platform other than web, replace the <code>pluginClass</code> in pubspec.yaml with a <code>dartPluginClass</code>. Here is the <code>hello_windows</code> example above modified for a Dart-only implementation:</p><div class="code-block-wrapper language-yaml"><div class="code-block-body"><span class="code-block-language" title="Language yaml">yaml</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">flutter</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> plugin</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> implements</span><span style="color:#222222">: </span><span style="color:#0C7064">hello</span></span> <span class="line"><span style="color:#0468D7"> platforms</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> windows</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> dartPluginClass</span><span style="color:#222222">: </span><span style="color:#0C7064">HelloPluginWindows</span></span></code></pre></div></div><p>In this version you would have no C++ Windows code, and would instead subclass the <code>hello</code> plugin's Dart platform interface class with a <code>HelloPluginWindows</code> class that includes a static <code>registerWith()</code> method. This method is called during startup, and can be used to register the Dart implementation:</p><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> HelloPluginWindows</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> HelloPluginPlatform</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#6E6E70"> /// Registers this class as the default instance of </span><span style="color:#222222">[HelloPluginPlatform]</span><span style="color:#6E6E70">.</span></span> <span class="line"><span style="color:#BD2314"> static</span><span style="color:#BD2314"> void</span><span style="color:#6200EE"> registerWith</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#0468D7"> HelloPluginPlatform</span><span style="color:#222222">.instance = </span><span style="color:#0468D7">HelloPluginWindows</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#222222"> }</span></span></code></pre></div></div><div class="header-wrapper"><h4 id="hybrid-platform-implementations">Hybrid platform implementations</h4><a class="heading-link" href="#hybrid-platform-implementations" aria-label="Link to 'Hybrid platform implementations' section">#</a></div><p>Platform implementations can also use both Dart and a platform-specific language. For example, a plugin could use a different platform channel for each platform so that the channels can be customized per platform.</p><p>A hybrid implementation uses both of the registration systems described above. Here is the <code>hello_windows</code> example above modified for a hybrid implementation:</p><div class="code-block-wrapper language-yaml"><div class="code-block-body"><span class="code-block-language" title="Language yaml">yaml</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">flutter</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> plugin</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> implements</span><span style="color:#222222">: </span><span style="color:#0C7064">hello</span></span> <span class="line"><span style="color:#0468D7"> platforms</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> windows</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> dartPluginClass</span><span style="color:#222222">: </span><span style="color:#0C7064">HelloPluginWindows</span></span> <span class="line"><span style="color:#0468D7"> pluginClass</span><span style="color:#222222">: </span><span style="color:#0C7064">HelloPlugin</span></span></code></pre></div></div><p>The Dart <code>HelloPluginWindows</code> class would use the <code>registerWith()</code> shown above for Dart-only implementations, while the C++ <code>HelloPlugin</code> class would be the same as in a C++-only implementation.</p><div class="header-wrapper"><h3 id="testing-your-plugin">Testing your plugin</h3><a class="heading-link" href="#testing-your-plugin" aria-label="Link to 'Testing your plugin' section">#</a></div><p>We encourage you test your plugin with automated tests to ensure that functionality doesn't regress as you make changes to your code.</p><p>To learn more about testing your plugins, check out <a href="/testing/testing-plugins">Testing plugins</a>. If you are writing tests for your Flutter app and plugins are causing crashes, check out <a href="/testing/plugins-in-tests">Flutter in plugin tests</a>.</p><div class="header-wrapper"><h2 id="plugin-ffi">Developing FFI plugin packages</h2><a class="heading-link" href="#plugin-ffi" aria-label="Link to 'Developing FFI plugin packages' section">#</a></div><p>If you want to develop a package that calls into native APIs using Dart's FFI, you need to develop an FFI plugin package.</p><p>Both FFI plugin packages and non-FFI plugin packages support bundling native code. However, FFI plugin packages don't support method channels, but they <em>do</em> support method channel registration code. To implement a plugin that uses both method channels <em>and</em> FFI, use a non-FFI plugin. Each platform can use either an FFI or non-FFI platform.</p><div class="header-wrapper"><h3 id="step-1-create-the-package-2">Step 1: Create the package</h3><a class="heading-link" href="#step-1-create-the-package-2" aria-label="Link to 'Step 1: Create the package' section">#</a></div><p>To create a starter FFI plugin package, use the <code>--template=plugin_ffi</code> flag with <code>flutter create</code>:</p><div class="code-block-wrapper language-console"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222" class="undefined terminal-command">flutter create --template=</span><span style="color:#0C7064">plugin_ffi</span><span style="color:#6200EE"> hello</span></span></code></pre></div></div><p>This creates an FFI plugin project in the <code>hello</code> folder with the following specialized content:</p><p><strong>lib</strong>: The Dart code that defines the API of the plugin, and which calls into the native code using <code>dart:ffi</code>.</p><p><strong>src</strong>: The native source code, and a <code>CMakeLists.txt</code> file for building that source code into a dynamic library.</p><p><strong>platform folders</strong> (<code>android</code>, <code>ios</code>, <code>windows</code>, etc.): The build files for building and bundling the native code library with the platform application.</p><div class="header-wrapper"><h3 id="step-2-building-and-bundling-native-code">Step 2: Building and bundling native code</h3><a class="heading-link" href="#step-2-building-and-bundling-native-code" aria-label="Link to 'Step 2: Building and bundling native code' section">#</a></div><p>The <code>pubspec.yaml</code> specifies FFI plugins as follows:</p><div class="code-block-wrapper language-yaml"><div class="code-block-body"><span class="code-block-language" title="Language yaml">yaml</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7"> plugin</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> platforms</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> some_platform</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> ffiPlugin</span><span style="color:#222222">: </span><span style="color:#0C7064">true</span></span></code></pre></div></div><p>This configuration invokes the native build for the various target platforms and bundles the binaries in Flutter applications using these FFI plugins.</p><p>This can be combined with <code>dartPluginClass</code>, such as when FFI is used for the implementation of one platform in a federated plugin:</p><div class="code-block-wrapper language-yaml"><div class="code-block-body"><span class="code-block-language" title="Language yaml">yaml</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7"> plugin</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> implements</span><span style="color:#222222">: </span><span style="color:#0C7064">some_other_plugin</span></span> <span class="line"><span style="color:#0468D7"> platforms</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> some_platform</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> dartPluginClass</span><span style="color:#222222">: </span><span style="color:#0C7064">SomeClass</span></span> <span class="line"><span style="color:#0468D7"> ffiPlugin</span><span style="color:#222222">: </span><span style="color:#0C7064">true</span></span></code></pre></div></div><p>A plugin can have both FFI and method channels:</p><div class="code-block-wrapper language-yaml"><div class="code-block-body"><span class="code-block-language" title="Language yaml">yaml</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7"> plugin</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> platforms</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> some_platform</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> pluginClass</span><span style="color:#222222">: </span><span style="color:#0C7064">SomeName</span></span> <span class="line"><span style="color:#0468D7"> ffiPlugin</span><span style="color:#222222">: </span><span style="color:#0C7064">true</span></span></code></pre></div></div><p>The native build systems that are invoked by FFI (and method channels) plugins are:</p><ul><li>For Android: Gradle, which invokes the Android NDK for native builds.<ul><li>See the documentation in <code>android/build.gradle</code>.</li></ul></li><li>For iOS and macOS: Xcode, using CocoaPods.<ul><li>See the documentation in <code>ios/hello.podspec</code>.</li><li>See the documentation in <code>macos/hello.podspec</code>.</li></ul></li><li>For Linux and Windows: CMake.<ul><li>See the documentation in <code>linux/CMakeLists.txt</code>.</li><li>See the documentation in <code>windows/CMakeLists.txt</code>.</li></ul></li></ul><div class="header-wrapper"><h3 id="step-3-binding-to-native-code">Step 3: Binding to native code</h3><a class="heading-link" href="#step-3-binding-to-native-code" aria-label="Link to 'Step 3: Binding to native code' section">#</a></div><p>To use the native code, bindings in Dart are needed.</p><p>To avoid writing these by hand, they are generated from the header file (<code>src/hello.h</code>) by <a href="https://pub.dev/packages/ffigen"><code>package:ffigen</code></a>. Reference the <a href="https://pub.dev/packages/ffigen/install">ffigen docs</a> for information on how to install this package.</p><p>Regenerate the bindings by running the following:</p><div class="code-block-wrapper language-console"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222" class="undefined terminal-command"> dart run ffigen --config ffigen.yaml</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="step-4-invoking-native-code">Step 4: Invoking native code</h3><a class="heading-link" href="#step-4-invoking-native-code" aria-label="Link to 'Step 4: Invoking native code' section">#</a></div><p>Very short-running native functions can be directly invoked from any isolate. For an example, see <code>sum</code> in <code>lib/hello.dart</code>.</p><p>Longer-running functions should be invoked on a <a href="https://dart.dev/guides/language/concurrency#background-workers">helper isolate</a> to avoid dropping frames in Flutter applications. For an example, see <code>sumAsync</code> in <code>lib/hello.dart</code>.</p><div class="header-wrapper"><h2 id="adding-documentation">Adding documentation</h2><a class="heading-link" href="#adding-documentation" aria-label="Link to 'Adding documentation' section">#</a></div><p>It is recommended practice to add the following documentation to all packages:</p><ol><li>A <code>README.md</code> file that introduces the package</li><li>A <code>CHANGELOG.md</code> file that documents changes in each version</li><li>A <a href="#adding-licenses-to-the-license-file"><code>LICENSE</code></a> file containing the terms under which the package is licensed</li><li>API documentation for all public APIs (see below for details)</li></ol><div class="header-wrapper"><h3 id="api-documentation">API documentation</h3><a class="heading-link" href="#api-documentation" aria-label="Link to 'API documentation' section">#</a></div><p>When you publish a package, API documentation is automatically generated and published to pub.dev/documentation. For example, see the docs for <a href="https://pub.dev/documentation/device_info_plus"><code>device_info_plus</code></a>.</p><p>If you wish to generate API documentation locally on your development machine, use the following commands:</p><ol><li><p>Change directory to the location of your package:</p><div class="code-block-wrapper language-console"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222">cd ~/dev/mypackage</span></span></code></pre></div></div></li><li><p>Tell the documentation tool where the Flutter SDK is located (change the following commands to reflect where you placed it):</p><div class="code-block-wrapper language-console"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222"> export FLUTTER_ROOT=~/dev/flutter # on macOS or Linux</span></span> <span class="line"></span> <span class="line"><span style="color:#222222"> set FLUTTER_ROOT=~/dev/flutter # on Windows</span></span></code></pre></div></div></li><li>Run the `dart doc` tool (included as part of the Flutter SDK), as follows:<div class="code-block-wrapper language-console"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222"> $FLUTTER_ROOT/bin/cache/dart-sdk/bin/dart doc # on macOS or Linux</span></span> <span class="line"></span> <span class="line"><span style="color:#222222"> %FLUTTER_ROOT%\bin\cache\dart-sdk\bin\dart doc # on Windows</span></span></code></pre></div></div></li></ol><p>For tips on how to write API documentation, see <a href="https://dart.dev/guides/language/effective-dart/documentation">Effective Dart Documentation</a>.</p><div class="header-wrapper"><h3 id="adding-licenses-to-the-license-file">Adding licenses to the LICENSE file</h3><a class="heading-link" href="#adding-licenses-to-the-license-file" aria-label="Link to 'Adding licenses to the LICENSE file' section">#</a></div><p>Individual licenses inside each LICENSE file should be separated by 80 hyphens on their own on a line.</p><p>If a LICENSE file contains more than one component license, then each component license must start with the names of the packages to which the component license applies, with each package name on its own line, and the list of package names separated from the actual license text by a blank line. (The packages need not match the names of the pub package. For example, a package might itself contain code from multiple third-party sources, and might need to include a license for each one.)</p><p>The following example shows a well-organized license file:</p><div class="code-block-wrapper language-plaintext"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span>package_1</span></span> <span class="line"><span></span></span> <span class="line"><span>&#x3C;some license text></span></span> <span class="line"><span></span></span> <span class="line"><span>--------------------------------------------------------------------------------</span></span> <span class="line"><span>package_2</span></span> <span class="line"><span></span></span> <span class="line"><span>&#x3C;some license text></span></span></code></pre></div></div><p>Here is another example of a well-organized license file:</p><div class="code-block-wrapper language-plaintext"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span>package_1</span></span> <span class="line"><span></span></span> <span class="line"><span>&#x3C;some license text></span></span> <span class="line"><span></span></span> <span class="line"><span>--------------------------------------------------------------------------------</span></span> <span class="line"><span>package_1</span></span> <span class="line"><span>package_2</span></span> <span class="line"><span></span></span> <span class="line"><span>&#x3C;some license text></span></span></code></pre></div></div><p>Here is an example of a poorly-organized license file:</p><div class="code-block-wrapper language-plaintext"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span>&#x3C;some license text></span></span> <span class="line"><span></span></span> <span class="line"><span>--------------------------------------------------------------------------------</span></span> <span class="line"><span>&#x3C;some license text></span></span></code></pre></div></div><p>Another example of a poorly-organized license file:</p><div class="code-block-wrapper language-plaintext"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span>package_1</span></span> <span class="line"><span></span></span> <span class="line"><span>&#x3C;some license text></span></span> <span class="line"><span>--------------------------------------------------------------------------------</span></span> <span class="line"><span>&#x3C;some license text></span></span></code></pre></div></div><div class="header-wrapper"><h2 id="publish">Publishing your package</h2><a class="heading-link" href="#publish" aria-label="Link to 'Publishing your package' section">#</a></div><aside class="alert alert-success"><div class="alert-header"><i class="material-symbols" aria-hidden="true">lightbulb</i> <span>Tip</span></div><div class="alert-content"><p>Have you noticed that some of the packages and plugins on pub.dev are designated as <a href="https://pub.dev/flutter/favorites">Flutter Favorites</a>? These are the packages published by verified developers and are identified as the packages and plugins you should first consider using when writing your app. To learn more, see the <a href="/packages-and-plugins/favorites">Flutter Favorites program</a>.</p></div></aside><p>Once you have implemented a package, you can publish it on <a href="https://pub.dev">pub.dev</a>, so that other developers can easily use it.</p><p>Prior to publishing, make sure to review the <code>pubspec.yaml</code>, <code>README.md</code>, and <code>CHANGELOG.md</code> files to make sure their content is complete and correct. Also, to improve the quality and usability of your package (and to make it more likely to achieve the status of a Flutter Favorite), consider including the following items:</p><ul><li>Diverse code usage examples</li><li>Screenshots, animated gifs, or videos</li><li>A link to the corresponding code repository</li></ul><p>Next, run the publish command in <code>dry-run</code> mode to see if everything passes analysis:</p><div class="code-block-wrapper language-console"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222" class="undefined terminal-command">flutter pub publish --dry-run</span></span></code></pre></div></div><p>The next step is publishing to pub.dev, but be sure that you are ready because <a href="https://dart.dev/tools/pub/publishing#publishing-is-forever">publishing is forever</a>:</p><div class="code-block-wrapper language-console"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222" class="undefined terminal-command">flutter pub publish</span></span></code></pre></div></div><p>For more details on publishing, see the <a href="https://dart.dev/tools/pub/publishing">publishing docs</a> on dart.dev.</p><div class="header-wrapper"><h2 id="dependencies">Handling package interdependencies</h2><a class="heading-link" href="#dependencies" aria-label="Link to 'Handling package interdependencies' section">#</a></div><p>If you are developing a package <code>hello</code> that depends on the Dart API exposed by another package, you need to add that package to the <code>dependencies</code> section of your <code>pubspec.yaml</code> file. The code below makes the Dart API of the <code>url_launcher</code> plugin available to <code>hello</code>:</p><div class="code-block-wrapper language-yaml"><div class="code-block-body"><span class="code-block-language" title="Language yaml">yaml</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">dependencies</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#0468D7"> url_launcher</span><span style="color:#222222">: </span><span style="color:#0C7064">^5.0.0</span></span></code></pre></div></div><p>You can now <code>import 'package:url_launcher/url_launcher.dart'</code> and <code>launch(someUrl)</code> in the Dart code of <code>hello</code>.</p><p>This is no different from how you include packages in Flutter apps or any other Dart project.</p><p>But if <code>hello</code> happens to be a <em>plugin</em> package whose platform-specific code needs access to the platform-specific APIs exposed by <code>url_launcher</code>, you also need to add suitable dependency declarations to your platform-specific build files, as shown below.</p><div class="header-wrapper"><h3 id="android">Android</h3><a class="heading-link" href="#android" aria-label="Link to 'Android' section">#</a></div><p>The following example sets a dependency for <code>url_launcher</code> in <code>hello/android/build.gradle</code>:</p><div class="code-block-wrapper language-groovy"><div class="code-block-body"><span class="code-block-language" title="Language groovy">groovy</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222">android {</span></span> <span class="line"><span style="color:#6E6E70"> // lines skipped</span></span> <span class="line"><span style="color:#222222"> dependencies {</span></span> <span class="line"><span style="color:#222222"> compileOnly rootProject.findProject(</span><span style="color:#0C7064">":url_launcher"</span><span style="color:#222222">)</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>You can now <code>import io.flutter.plugins.urllauncher.UrlLauncherPlugin</code> and access the <code>UrlLauncherPlugin</code> class in the source code at <code>hello/android/src</code>.</p><p>For more information on <code>build.gradle</code> files, see the <a href="https://docs.gradle.org/current/userguide/tutorial_using_tasks.html">Gradle Documentation</a> on build scripts.</p><div class="header-wrapper"><h3 id="ios">iOS</h3><a class="heading-link" href="#ios" aria-label="Link to 'iOS' section">#</a></div><p>The following example sets a dependency for <code>url_launcher</code> in <code>hello/ios/hello.podspec</code>:</p><div class="code-block-wrapper language-ruby"><div class="code-block-body"><span class="code-block-language" title="Language ruby">ruby</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">Pod</span><span style="color:#222222">::</span><span style="color:#0468D7">Spec</span><span style="color:#222222">.</span><span style="color:#BD2314">new</span><span style="color:#BD2314"> do</span><span style="color:#222222"> |s|</span></span> <span class="line"><span style="color:#6E6E70"> # lines skipped</span></span> <span class="line"><span style="color:#222222"> s.dependency </span><span style="color:#0C7064">'url_launcher'</span></span></code></pre></div></div><p>You can now <code>#import &quot;UrlLauncherPlugin.h&quot;</code> and access the <code>UrlLauncherPlugin</code> class in the source code at <code>hello/ios/Classes</code>.</p><p>For additional details on <code>.podspec</code> files, see the <a href="https://guides.cocoapods.org/syntax/podspec.html">CocoaPods Documentation</a>.</p><div class="header-wrapper"><h3 id="web">Web</h3><a class="heading-link" href="#web" aria-label="Link to 'Web' section">#</a></div><p>All web dependencies are handled by the <code>pubspec.yaml</code> file, like any other Dart package.</p><p id="page-github-links"><span>Unless stated otherwise, the documentation on this site reflects the latest stable version of Flutter. Page last updated on 2024-11-20.</span> <a href="https://github.com/flutter/website/tree/main/src/content/packages-and-plugins/developing-packages.md" target="_blank" rel="noopener">View source</a> <span>or </span><a href="https://github.com/flutter/website/issues/new?template=1_page_issue.yml&&page-url=https://docs.flutter.dev/packages-and-plugins/developing-packages/&page-source=https://github.com/flutter/website/tree/main/src/content/packages-and-plugins/developing-packages.md" title="Report an issue with this page" target="_blank" rel="noopener">report an issue</a>.</p></div></main></div></div><footer class="site-footer"><div class="container-fluid"><div class="row"><div class="col-md-12 site-footer__wrapper"><div class="site-footer__logo"><img src="/assets/images/branding/flutter/logo/flutter-mono-81x100.png" alt="Flutter Logo" width="81" height="100"></div><div class="site-footer__content"><ul class="site-footer__link-list"><li><a href="/tos">terms</a></li><li><a href="/brand">brand usage</a></li><li><a href="/security">security</a></li><li><a href="https://www.google.com/intl/en/policies/privacy">privacy</a></li><li><a href="https://esflutter.dev/">español</a></li><li><a href="https://flutter.cn" class="text-nowrap">社区中文资源</a></li><li><a href="https://blog.google/inside-google/company-announcements/standing-with-black-community">We stand in solidarity with the Black community. Black Lives Matter.</a></li></ul><p class="licenses">Except as otherwise noted, this work is licensed under a <a rel="license" href="https://creativecommons.org/licenses/by/4.0">Creative Commons Attribution 4.0 International License</a>, and code samples are licensed under the BSD License.</p></div></div></div></div></footer><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js" integrity="sha512-3gJwYpMe3QewGELv8k/BX9vcqhryRdzRMxVfq6ngyWXwo03GFEzjsUm8Q7RZcHPHksttq7/GFoxjCVUjkjvPdw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/js/bootstrap.min.js" integrity="sha512-7rusk8kGPFynZWu26OKbTeI+QPoYchtxsmPeBqkHIEXJxeun4yJ4ISYe7C6sz9wdxeE1Gk3VxsIWgCZTc+vX3g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script><script src="/assets/js/tabs.js"></script><script src="/assets/js/archive.js"></script><script src="/assets/js/main.js"></script></body></html>

Pages: 1 2 3 4 5 6 7 8 9 10