flet
Write entire Flutter app in Python or add server-driven UI experience into existing Flutter app.
0.86.5
19K downloads/mo
#2266 most downloaded on pub.dev
flet-dev/flet
What this package is like to depend on
Last release 22 days ago
01 Aug 2026
Ships fairly regularly
a new release about every 2 weeks
Nearly every release is documented
notes for 89 of 91 stable releases
1 version withdrawn
withdrawn after publishing
4 years old
92 releases · first in 2022
23 releases in the last 12 months
see the full history below
Release timeline
92 releases · Oct 2022 to Aug 2026Releases
latest 60 of 92-
0.86.501 Aug 2026Release notes
Open source →Bug fixes
- Fix every
flet_adscontrol (BannerAd,InterstitialAd,NativeAd,ConsentManager) crashing on construction withRuntimeError: <Ad>(N) Control must be added to the page first, which made the package unusable since 0.85. The mobile-only platform guard readself.pagefrominit(), which runs at construction — before the control is attached to the page — so the parent-chain lookup raised. The guard is back inbefore_update(), a post-mount hook whereself.pageresolves, so ads construct freely and only reject web/desktop at mount time (#6726, #6735) by @ndonkoHenri.
Improvements
-
An Android permission set to
falseis now actively removed from the merged manifest instead of merely being left out of the generated one. Gradle's manifest merger folds in the manifest of every Flutter plugin and can also synthesize permissions on its own, andfalsepreviously had no effect on either — the template only skipped emitting the entry, so a plugin-contributed permission passed straight through with no way to stop it. Concretely:flet-camerapulls incamera_android_camerax, which declaresWRITE_EXTERNAL_STORAGEbounded tomaxSdkVersion="28", and the merger implies an unboundedREAD_EXTERNAL_STORAGEfrom it (legacy behaviour — write once implied read). Both then appear in the Play Console despite being absent frompyproject.toml, and the unbounded read is exactly the shape Google Play's storage policy objects to. Permissions set tofalsenow render as<uses-permission android:name="…" tools:node="remove" />(the template's<manifest>gained thetoolsnamespace), which strips them during the merge; removing a permission nothing declares is a harmless no-op. Verified on Flet Studio: 11 permissions down to 9, both storage entries gone from the built APK by @FeodorFitsner. -
Bumped
serious_pythonto 4.5.1 and re-pinned the bundled python-build snapshot to 20260730 (dart_bridge1.7.1).serious_python4.5.1 tracks the same python-build release, keepingPYTHON_BUILD_RELEASE_DATEin sync with itspythonReleaseDateas the pin requires by @FeodorFitsner. -
Android ProGuard/R8 rules can now be extended from
pyproject.tomlvia[tool.flet.android].proguard_rules. The generated project'sandroid/app/proguard-rules.prowas a fixed template file, so an app that needed an extra keep rule had no way to add one short of downloading the published build template, patching the file and passing--template. This matters for Pyjnius:autoclass()resolves Java classes by name at runtime, and R8 renames anything in the APK that isn't kept — soautoclass()on a class bundled by a Flutter plugin or by your own Java/Kotlin fails in release builds. It fails hard: JNIFindClassreturns null and the process aborts withJNI DETECTED ERROR IN APPLICATION: obj == null/SIGABRTrather than raising a catchable Python exception, and because R8 only runs in release builds it never reproduces in debug. Android framework classes (android.os.Buildand friends) live outside the APK and never needed a rule. Rules are appended to the defaults, since R8 has no directive that undoes a keep; to remove the defaults instead — in particular-keepnames class * { *; }, which keeps every class and member name in the app and costs 2.5 MB ofclasses.dexon Flet Studio (5.9 MB → 3.4 MB, -43%) — set[tool.flet.android].proguard_default_rules = false. Dropping the defaults is safe for Pyjnius'sPythonActivityaccess, becauseserious_python_android4.1.0+ ships that keep rule in its ownconsumer-rules.pro. Defaults are unchanged, so existing builds render exactly the same file by @FeodorFitsner. -
Android Gradle properties can now be configured from
pyproject.tomlvia[tool.flet.android.gradle_properties]. The generated project'sandroid/gradle.propertieswas previously fixed, so its memory settings —org.gradle.jvmargs=-Xmx8Gplus a 4 GB metaspace — could not be changed. That is larger than the total RAM of a standard GitHub-hosted runner (measured: 7.8 GB with 3 GB of swap), so release builds, which additionally run Dart AOT once per ABI and R8, could exhaust memory and stall with no error; the only workaround was to download the published build template, patch the file and pass--template. Entries in the table override the defaults or add new properties, e.g."org.gradle.jvmargs" = "-Xmx3G -XX:MaxMetaspaceSize=1G"and"org.gradle.workers.max" = 2. Defaults are unchanged, so existing builds render exactly the same file by @FeodorFitsner.
Full Changelog: v0.86.4...v0.86.5
Release notes
Open source →Bug fixes
- Fix every
flet_adscontrol (BannerAd,InterstitialAd,NativeAd,ConsentManager) crashing on construction withRuntimeError: <Ad>(N) Control must be added to the page first, which made the package unusable since 0.85. The mobile-only platform guard readself.pagefrominit(), which runs at construction — before the control is attached to the page — so the parent-chain lookup raised. The guard is back inbefore_update(), a post-mount hook whereself.pageresolves, so ads construct freely and only reject web/desktop at mount time (#6726, #6735) by @ndonkoHenri.
Improvements
-
An Android permission set to
falseis now actively removed from the merged manifest instead of merely being left out of the generated one. Gradle's manifest merger folds in the manifest of every Flutter plugin and can also synthesize permissions on its own, andfalsepreviously had no effect on either — the template only skipped emitting the entry, so a plugin-contributed permission passed straight through with no way to stop it. Concretely:flet-camerapulls incamera_android_camerax, which declaresWRITE_EXTERNAL_STORAGEbounded tomaxSdkVersion="28", and the merger implies an unboundedREAD_EXTERNAL_STORAGEfrom it (legacy behaviour — write once implied read). Both then appear in the Play Console despite being absent frompyproject.toml, and the unbounded read is exactly the shape Google Play's storage policy objects to. Permissions set tofalsenow render as<uses-permission android:name="…" tools:node="remove" />(the template's<manifest>gained thetoolsnamespace), which strips them during the merge; removing a permission nothing declares is a harmless no-op. Verified on Flet Studio: 11 permissions down to 9, both storage entries gone from the built APK (#6742) by @FeodorFitsner. -
Bumped
serious_pythonto 4.5.1 and re-pinned the bundled python-build snapshot to 20260730 (dart_bridge1.7.1).serious_python4.5.1 tracks the same python-build release, keepingPYTHON_BUILD_RELEASE_DATEin sync with itspythonReleaseDateas the pin requires (#6742) by @FeodorFitsner. -
Android ProGuard/R8 rules can now be extended from
pyproject.tomlvia[tool.flet.android].proguard_rules. The generated project'sandroid/app/proguard-rules.prowas a fixed template file, so an app that needed an extra keep rule had no way to add one short of downloading the published build template, patching the file and passing--template. This matters for Pyjnius:autoclass()resolves Java classes by name at runtime, and R8 renames anything in the APK that isn't kept — soautoclass()on a class bundled by a Flutter plugin or by your own Java/Kotlin fails in release builds. It fails hard: JNIFindClassreturns null and the process aborts withJNI DETECTED ERROR IN APPLICATION: obj == null/SIGABRTrather than raising a catchable Python exception, and because R8 only runs in release builds it never reproduces in debug. Android framework classes (android.os.Buildand friends) live outside the APK and never needed a rule. Rules are appended to the defaults, since R8 has no directive that undoes a keep; to remove the defaults instead — in particular-keepnames class * { *; }, which keeps every class and member name in the app and costs 2.5 MB ofclasses.dexon Flet Studio (5.9 MB → 3.4 MB, -43%) — set[tool.flet.android].proguard_default_rules = false. Dropping the defaults is safe for Pyjnius'sPythonActivityaccess, becauseserious_python_android4.1.0+ ships that keep rule in its ownconsumer-rules.pro. Defaults are unchanged, so existing builds render exactly the same file (#6741) by @FeodorFitsner. -
Android Gradle properties can now be configured from
pyproject.tomlvia[tool.flet.android.gradle_properties]. The generated project'sandroid/gradle.propertieswas previously fixed, so its memory settings —org.gradle.jvmargs=-Xmx8Gplus a 4 GB metaspace — could not be changed. That is larger than the total RAM of a standard GitHub-hosted runner (measured: 7.8 GB with 3 GB of swap), so release builds, which additionally run Dart AOT once per ABI and R8, could exhaust memory and stall with no error; the only workaround was to download the published build template, patch the file and pass--template. Entries in the table override the defaults or add new properties, e.g."org.gradle.jvmargs" = "-Xmx3G -XX:MaxMetaspaceSize=1G"and"org.gradle.workers.max" = 2. Defaults are unchanged, so existing builds render exactly the same file (#6732, #6733) by @FeodorFitsner.
Release notes
Open source →No changes in the
fletDart package; version bumped for release coordination with configurable Androidgradle.propertieson the Python side (#6733). - Fix every
-
0.86.427 Jul 2026Release notes
Open source →Bug fixes
- Fix services registered after an embedded
FletAppis opened never becoming usable on the host page — calling one failed withTimeout waiting for invoke method listener for <Service>(id).<method>.ServiceRegistrysubclassesService, so it registered itself on construction; when an embedded app's page built its own registry while the host page was still the current context, the embedded registry was registered as a service inside the host's registry. The client has no binding for a control of typeServiceRegistry, so building it threwUnknown serviceinside the host's service loop and aborted it, leaving every service positioned after that entry unbound — permanently, since the entry stays in the list. A registry is the container for services, not a service, so it no longer self-registers; the client-side loop also isolates per-service failures now, so a single unbuildable entry can't stop the rest from binding. Reproduced with a host app embedding aFletAppand registering aClipboardafterwards by @FeodorFitsner.
Full Changelog: v0.86.3...v0.86.4
Release notes
Open source →Bug fixes
- Fix services registered after an embedded
FletAppis opened never becoming usable on the host page — calling one failed withTimeout waiting for invoke method listener for <Service>(id).<method>.ServiceRegistrysubclassesService, so it registered itself on construction; when an embedded app's page built its own registry while the host page was still the current context, the embedded registry was registered as a service inside the host's registry. The client has no binding for a control of typeServiceRegistry, so building it threwUnknown serviceinside the host's service loop and aborted it, leaving every service positioned after that entry unbound — permanently, since the entry stays in the list. A registry is the container for services, not a service, so it no longer self-registers; the client-side loop also isolates per-service failures now, so a single unbuildable entry can't stop the rest from binding. Reproduced with a host app embedding aFletAppand registering aClipboardafterwards (#6728) by @FeodorFitsner.
Release notes
Open source →- Isolate per-service failures when building the page's service registry.
ServiceBindingthrowsUnknown servicefor a control type no extension can build, and that exception escapingServiceRegistry._onServicesUpdated()aborted the whole loop, so every service after the offending entry was silently never bound and laterinvokeMethodcalls on them hung until they timed out. Each binding is now built independently and a failure is logged and skipped. Also rebuilds the registry when the_servicescontrol instance is replaced (not just when its uid changes), matching how thewindowservice tracks its control by identity.
- Fix services registered after an embedded
-
0.86.326 Jul 2026Release notes
Open source →Improvements
-
An embedded
FletAppcan now run over the in-processdart_bridgetransport instead of a socket. Seturl="dartbridge://"and the client allocates a native channel, delivers its port through the newFletApp.on_connectevent, and the host serves that port with aFletDartBridgeServer— so a Flet program hosted inside another Flet app (a gallery, a preview) exchanges messages at memcpy speed with no socket file, no TCP port, and noAF_UNIXpath-length limit (which broke embedded apps on the iOS simulator, where the container path overflowssun_path). High-throughputDataChannels used by embedded apps (RawImage,MatplotlibChart) get their own dedicated bridge too. The transport is opt-in and falls back to the existing URL-scheme channels: on web and desktop dev builds, wheredart_bridgeis unavailable, hosts keep using a socket URL by @FeodorFitsner. -
flet runcan now pass custom arguments to your app script: everything after a--separator is forwarded to the script instead of being parsed by Flet, and arrives there assys.argv[1:]- e.g.flet run --web main.py -- --dataset big.csv --verbose. Previously there was no way to do this: the app was always launched aspython -u <script>with no extra arguments, so a flag meant for the app was consumed by the CLI's own parser and rejected withflet: error: unrecognized arguments: --verbose. The arguments are re-applied on every hot reload and work in all run modes (desktop,--web,--ios,--android, and-mmodule invocations). Arguments that don't look like options can be passed without the separator (flet run main.py big.csv), and mistyped Flet options are still reported as errors - now with a hint to use--when they were meant for the app. See Passing arguments to your app by @FeodorFitsner.
Bug fixes
-
Fix iOS apps built with
flet build ipacrashing at startup withFailed to lookup symbol 'serious_python_run': dlsym(RTLD_DEFAULT, serious_python_run): symbol not found.serious_pythonshippeddart_bridge— which provides the in-process Dart↔Python transport — as a static library linked into the app executable. An iOS executable exports nothing to the dynamic symbol table by default and the release build strips local symbols, so thedlsymlookups that Dart (DynamicLibrary.process()) and Python (import dart_bridge) perform at runtime could not resolve. Only release/archive (device) builds under the Swift Package Manager path were affected — debug and simulator builds don't dead-strip, so the failure did not reproduce there, and Android was never affected (itsdart_bridgeis a dynamic.so, which exports its symbols). Bumpsserious_pythonto 4.4.0, which shipsdart_bridgeas a dynamic framework — embedded and signed into the app likePython.xcframework, with its symbols exported — and re-pins the bundled python-build snapshot to 20260726 (dart_bridge1.5.1 → 1.6.1, Pyodide 3.14 314.0.2 → 314.0.3); the bundled Python versions (3.12.13 / 3.13.14 / 3.14.6) are unchanged by @FeodorFitsner. -
Fix
MatplotlibChartfreezing permanently when its platform view is disposed with a frame in flight — the common trigger is switching to another tab inside the app, which races the frame stream:DataChannel.sendon a disposed channel silently drops, so the frame's[0xFF]frame-applied ack never arrives and_send_and_wait's unbounded await parksMatplotlibChart._receive_loop— the sole consumer of the frame queue — for the rest of the session, with no exception raised; remounting opens a fresh channel but the stale ack futures were never resolved, so the chart stayed frozen._capture_channelnow resolves all pending ack futures when a new channel is captured (a fresh channel means every pending ack belongs to the disposed one), unparking the producer instantly on remount, and the ack await is bounded byFRAME_ACK_TIMEOUT(5s; a healthy ack lands in milliseconds) — on expiry the frame is dropped and its future removed from the ack FIFO so subsequent acks keep resolving the right entries (#6709, #6710) by @ForsakenDurian. -
Fix a system/edge-swipe back gesture exiting the whole host app instead of navigating back when it lands on an embedded
FletApp(an app rendered inside another Flet app — e.g. a gallery host running example apps in-process). The embedded app'sWidgetsApp(MaterialApp/CupertinoApp) ran the defaultNavigationNotificationhandler, which reportedSystemNavigator.setFrameworkHandlesBack(false)for a nested app that couldn't pop (typically a single-view example) and swallowed the notification, so the OS finished the whole activity on back and the host never got to report that it could pop. An embedded page now lets that notification bubble to the host (which re-reportscanHandlePop) and chains aChildBackButtonDispatcherto the host Router, so a system back propagates to the host and pops the view that embeds it by @FeodorFitsner. -
Fix
page.window.maximized = Trueintermittently reverting to unmaximized right after startup on macOS, when set in the same patch aspage.title(e.g.page.title = "My App"; page.window.maximized = Trueinmain()) by @davidlawson. -
Fix
flet buildpicking a non-decodable icon/splash image when several files share a base name, producing a machine-dependentNoDecoderForImageFormatExceptionfromflutter_launcher_icons. When an app'sassetsheld, say, bothicon.pngandicon.svg,find_platform_imageselected the first match fromglob.glob(...)— whose order is filesystem-dependent — so the same app could pickicon.pngon one machine andicon.svgon another (SVG is vector and can't be decoded by the raster icon/splash generators), turning a working build into a crash purely based on directory listing order. Candidates are now filtered to formats the generators can actually decode (.svgis dropped everywhere;.icnsstays macOS-only and.icoWindows-only) and ranked so a raster image (.pngfirst) always wins, making the choice deterministic across machines. When the only supplied image is an SVG (no raster sibling), it's skipped with a build-log warning and the default Flet icon is used instead of crashing by @FeodorFitsner. -
Fix modal controls (
AlertDialog,CupertinoAlertDialog,BottomSheet,CupertinoBottomSheet) crashing to a black screen with "setState()/markNeedsBuild() called during build" when they close in the same frame that another route or overlay opens — e.g. dismissing a bottom sheet and showing aSnackBarfrom one handler. The close path popped the route synchronously duringbuild, so the exit animation notified a listener that was mid-build. Each modal now tracks its ownModalRouteand closes it in a post-frame callback, popping that route (never the topmost one);View's confirm-pop pops its own route too, so a modal dismissed in the same tick as a view pop can no longer dismiss the wrong one by @FeodorFitsner.
Full Changelog: v0.86.2...v0.86.3
Release notes
Open source →Improvements
-
An embedded
FletAppcan now run over the in-processdart_bridgetransport instead of a socket. Seturl="dartbridge://"and the client allocates a native channel, delivers its port through the newFletApp.on_connectevent, and the host serves that port with aFletDartBridgeServer— so a Flet program hosted inside another Flet app (a gallery, a preview) exchanges messages at memcpy speed with no socket file, no TCP port, and noAF_UNIXpath-length limit (which broke embedded apps on the iOS simulator, where the container path overflowssun_path). High-throughputDataChannels used by embedded apps (RawImage,MatplotlibChart) get their own dedicated bridge too. The transport is opt-in and falls back to the existing URL-scheme channels: on web and desktop dev builds, wheredart_bridgeis unavailable, hosts keep using a socket URL (#6723) by @FeodorFitsner. -
flet runcan now pass custom arguments to your app script: everything after a--separator is forwarded to the script instead of being parsed by Flet, and arrives there assys.argv[1:]- e.g.flet run --web main.py -- --dataset big.csv --verbose. Previously there was no way to do this: the app was always launched aspython -u <script>with no extra arguments, so a flag meant for the app was consumed by the CLI's own parser and rejected withflet: error: unrecognized arguments: --verbose. The arguments are re-applied on every hot reload and work in all run modes (desktop,--web,--ios,--android, and-mmodule invocations). Arguments that don't look like options can be passed without the separator (flet run main.py big.csv), and mistyped Flet options are still reported as errors - now with a hint to use--when they were meant for the app. See Passing arguments to your app (#6721) by @FeodorFitsner.
Bug fixes
-
Fix iOS apps built with
flet build ipacrashing at startup withFailed to lookup symbol 'serious_python_run': dlsym(RTLD_DEFAULT, serious_python_run): symbol not found.serious_pythonshippeddart_bridge— which provides the in-process Dart↔Python transport — as a static library linked into the app executable. An iOS executable exports nothing to the dynamic symbol table by default and the release build strips local symbols, so thedlsymlookups that Dart (DynamicLibrary.process()) and Python (import dart_bridge) perform at runtime could not resolve. Only release/archive (device) builds under the Swift Package Manager path were affected — debug and simulator builds don't dead-strip, so the failure did not reproduce there, and Android was never affected (itsdart_bridgeis a dynamic.so, which exports its symbols). Bumpsserious_pythonto 4.4.0, which shipsdart_bridgeas a dynamic framework — embedded and signed into the app likePython.xcframework, with its symbols exported — and re-pins the bundled python-build snapshot to 20260727 (dart_bridge1.5.1 → 1.6.1, Pyodide 3.14 314.0.2 → 314.0.3); the bundled Python versions (3.12.13 / 3.13.14 / 3.14.6) are unchanged (#6723) by @FeodorFitsner. -
Fix
MatplotlibChartfreezing permanently when its platform view is disposed with a frame in flight — the common trigger is switching to another tab inside the app, which races the frame stream:DataChannel.sendon a disposed channel silently drops, so the frame's[0xFF]frame-applied ack never arrives and_send_and_wait's unbounded await parksMatplotlibChart._receive_loop— the sole consumer of the frame queue — for the rest of the session, with no exception raised; remounting opens a fresh channel but the stale ack futures were never resolved, so the chart stayed frozen._capture_channelnow resolves all pending ack futures when a new channel is captured (a fresh channel means every pending ack belongs to the disposed one), unparking the producer instantly on remount, and the ack await is bounded byFRAME_ACK_TIMEOUT(5s; a healthy ack lands in milliseconds) — on expiry the frame is dropped and its future removed from the ack FIFO so subsequent acks keep resolving the right entries (#6709, #6710) by @ForsakenDurian. -
Fix a system/edge-swipe back gesture exiting the whole host app instead of navigating back when it lands on an embedded
FletApp(an app rendered inside another Flet app — e.g. a gallery host running example apps in-process). The embedded app'sWidgetsApp(MaterialApp/CupertinoApp) ran the defaultNavigationNotificationhandler, which reportedSystemNavigator.setFrameworkHandlesBack(false)for a nested app that couldn't pop (typically a single-view example) and swallowed the notification, so the OS finished the whole activity on back and the host never got to report that it could pop. An embedded page now lets that notification bubble to the host (which re-reportscanHandlePop) and chains aChildBackButtonDispatcherto the host Router, so a system back propagates to the host and pops the view that embeds it (#6715) by @FeodorFitsner. -
Fix
page.window.maximized = Trueintermittently reverting to unmaximized right after startup on macOS, when set in the same patch aspage.title(e.g.page.title = "My App"; page.window.maximized = Trueinmain()) (#6712) by @davidlawson. -
Fix
flet buildpicking a non-decodable icon/splash image when several files share a base name, producing a machine-dependentNoDecoderForImageFormatExceptionfromflutter_launcher_icons. When an app'sassetsheld, say, bothicon.pngandicon.svg,find_platform_imageselected the first match fromglob.glob(...)— whose order is filesystem-dependent — so the same app could pickicon.pngon one machine andicon.svgon another (SVG is vector and can't be decoded by the raster icon/splash generators), turning a working build into a crash purely based on directory listing order. Candidates are now filtered to formats the generators can actually decode (.svgis dropped everywhere;.icnsstays macOS-only and.icoWindows-only) and ranked so a raster image (.pngfirst) always wins, making the choice deterministic across machines. When the only supplied image is an SVG (no raster sibling), it's skipped with a build-log warning and the default Flet icon is used instead of crashing (#6707) by @FeodorFitsner. -
Fix modal controls (
AlertDialog,CupertinoAlertDialog,BottomSheet,CupertinoBottomSheet) crashing to a black screen with "setState()/markNeedsBuild() called during build" when they close in the same frame that another route or overlay opens — e.g. dismissing a bottom sheet and showing aSnackBarfrom one handler. The close path popped the route synchronously duringbuild, so the exit animation notified a listener that was mid-build. Each modal now tracks its ownModalRouteand closes it in a post-frame callback, popping that route (never the topmost one);View's confirm-pop pops its own route too, so a modal dismissed in the same tick as a view pop can no longer dismiss the wrong one (#6714) by @FeodorFitsner.
Release notes
Open source →- Fix a system/edge-swipe back gesture exiting the whole host app instead of navigating back when it lands on an embedded
FletApp(an app rendered inside another Flet app — e.g. a gallery host running example apps in-process). The embedded app'sWidgetsApp(MaterialApp/CupertinoApp) ran the defaultNavigationNotificationhandler, which reportedSystemNavigator.setFrameworkHandlesBack(false)for a nested app that couldn't pop (typically a single-view example) and swallowed the notification, so the OS finished the whole activity on back and the host never got to report that it could pop. An embedded page now lets that notification bubble to the host (which re-reportscanHandlePop) and chains aChildBackButtonDispatcherto the host Router, so a system back propagates to the host and pops the view that embeds it. - Fix modal controls (
AlertDialog,CupertinoAlertDialog,BottomSheet,CupertinoBottomSheet) throwing "setState()/markNeedsBuild() called during build" and blanking the screen when closed in the same frame another route/overlay opens (e.g. aSnackBar). Each modal now tracks its ownModalRouteand closes it via a post-framecloseModalRoute()that pops that specific route;View's confirm-pop pops its own route too, removing the wrong-route race between a dismissing modal and a view pop.
-
-
0.86.222 Jul 2026Release notes
Open source →Bug fixes
- Fix code edits not taking effect under
flet debug android: after re-running the command, the app kept executing the previously-unpacked, stale code instead of your changes.flet debugrebuilds and reinstalls the same-version APK on each iteration (flutter rundoes an update install that preserves app data), andserious_python's on-device extraction cache — keyed only onversionName+versionCode— never saw the version change, so it skipped re-unpacking the newapp.zip. Bumpsserious_pythonto 4.3.4, which folds the APK'slastUpdateTimeinto that cache key so every (re)install re-extracts the current code while ordinary relaunches still hit the cache.flet build apkwas never affected (#6682) by @FeodorFitsner. - Fix an embedded
FletApp(an app rendered inside another Flet app — e.g. a preview or gallery host that runs example apps in-process) not refreshing its UI in response to events. Auto-update mode was tracked ascomponents_modeon a single process-globalcontextsingleton, so a host app that rendered viapage.render/page.render_viewsturned components mode on process-wide andcontext.auto_update_enabled()then returnedFalsefor the embedded app too — any handler that mutated a control without calling.update()(the common imperative style, including allpage.servicessensor readings) silently never re-rendered. Event dispatch also ran in a fresh task whose page context var could carry a different session's page, so context-derived state resolved against the wrong session.components_modeis now stored per-Session, andSession.dispatch_eventbinds the page context to its own session before invoking handlers, so multiple Flet apps sharing one process keep independent update behavior by @FeodorFitsner. - Modernize examples for 0.86: replace the removed
TextField.error_textwitherror(chat tutorial,mind_queue,palette_editor), and declare the device permissions each sensor example needs to run on-device —NSMotionUsageDescriptionon iOS for the motion/barometer sensors andandroid.permission.VIBRATEfor HapticFeedback by @FeodorFitsner. - Fix opening a
flet run --ios/--androidapp URL in a desktop browser: the page loaded but stayed on the boot screen, endlessly retrying a WebSocket connection tows://<host>:<port>/ws. Mobile-mode apps are mounted under a non-root path (e.g./counter/main.py), so the real WebSocket route lives at/counter/main.py/ws- but since 1.0 Alpha the FastAPI wrapper always passed the bare defaultwsendpoint name intoFletStaticFiles, bypassing its mount-path-aware fallback, andindex.htmlgot patched withflet.webSocketEndpoint="ws", which the web client resolves against the server root. The native iOS/Android client derives the path from the page URL and was unaffected. A relative WebSocket endpoint is now resolved against the app mount path when patchingindex.html, fixing browser access to any Flet web app mounted under a non-root path (--ios/--android,flet run --name, or aflet_web.fastapiapp mounted at a sub-path) by @FeodorFitsner. - Fix web
RawImageandMatplotlibChartanimations flooding the console with uncatchable engine exceptions (and breaking the animation) after the browser tab was backgrounded for a while and then refocused. On Flet web the frame producer runs in a Pyodide worker (or on a remote server over a WebSocket) that the browser never throttles, while the client's Flutter frame pipeline is suspended whenever the tab is hidden - sosetStateschedules frames that never paint and the post-frame callbacks that dispose replacedui.Images never fire. Decoded images and pending disposals then pile up unbounded in the Dart heap and flush into the engine all at once on resume, one exception per queued frame. This is a client-side accumulation independent of transport, so it also affected native windows minimized with an animation running. Fixed in two layers: (1) a sharedFrameStreamVisibilityclient-side mixin - used by bothRawImageandflet-charts'MatplotlibChartCanvas- stops decoding/uploading and frees replaced images immediately while hidden (keeping only cheap offscreen state up to date, so incremental matplotlib diffs stay correct), then presents just the latest frame on resume; (2) a newpage.wait_until_visible()gate (driven byon_app_lifecycle_state_change, alongside apage.app_visibleproperty) that the streaming controls await internally, so producer loops park while hidden instead of rendering frames a suspended client can only discard (#6691) by @FeodorFitsner. - Fix
flet build/flet publishflooding non-interactive logs (CI, cloud build, any piped stdout) with thousands of progress-spinner frames, and fix the--no-rich-outputflag not actually producing plain output. The CLI's richConsolewas created withforce_terminal=Truewhenever theFLET_CLI_NO_RICH_OUTPUTenv var was unset, which forces theLivestatus spinner to repaint even when stdout isn't a TTY — so in a pipe every animation frame lands on its own line (e.g. hundreds of( ● ) Initializing web build...lines). And the--no-rich-outputCLI flag never reached that console at all: it's parsed per-command, after the module-levelconsoleis already built, so it only suppressed emojis while color and the spinner kept going. Now the console auto-detects the terminal (force_terminal=None) — interactive terminals keep the animated spinner while piped output stays quiet — and bothFLET_CLI_NO_RICH_OUTPUTand--no-rich-output(detected fromsys.argvat import) force fully plain output by @FeodorFitsner.
Improvements
- Flutter updated to 3.44.7.
- Fix
flet_video.Videoresetting itsvolume(andpitch,playback_rate,shuffle_playlist,playlist_mode,subtitle_track) to the player's defaults after togglingvisibleoff then on — e.g.volumejumped back to100. Hiding aVideodisposes its nativemedia_kitplayer and showing it recreates a fresh one at default settings; the "last-applied" tracking now lives with the player (not the persistent control model) and is reset on recreation, sobuild()re-applies every setting to the new player (#6683, #6694) by @ndonkoHenri. - Fix
SearchBar.on_tap_outside_barnot firing when the user tapped outside the open search view. That case now has a dedicatedSearchBar.on_tap_outside_viewevent (fired when tapping outside the open view, e.g. to dismiss it), andon_tap_outside_baris documented to match what it actually does: fire while the bar is focused and the view is closed, likeTextField.on_tap_outside(#6593, #6697) by @ndonkoHenri. - Add a
--android-legacy-packagingflag (and[tool.flet.android].legacy_packagingsetting) toflet build apk/aabfor opting into legacy Android native-library packaging. By default (modern packaging), native.sofiles are stored uncompressed and page-aligned in the APK and memory-mapped directly at runtime, which typically gives a smaller install and Play Store download but a larger raw.apkfile. Enabling this option setsuseLegacyPackaging = trueso the.soare compressed inside the APK and extracted to disk on install: the raw.apkfile is smaller (handy when side-loading), at the cost of a larger on-device install and slower native-library loading. The extraction directory is exposed to Python asANDROID_NATIVE_LIBRARY_DIR, which can help custom native-library consumers that require a real filesystem path. See Native library packaging by @FeodorFitsner.
Full Changelog: v0.86.1...v0.86.2
Release notes
Open source →Bug fixes
- Fix code edits not taking effect under
flet debug android: after re-running the command, the app kept executing the previously-unpacked, stale code instead of your changes.flet debugrebuilds and reinstalls the same-version APK on each iteration (flutter rundoes an update install that preserves app data), andserious_python's on-device extraction cache — keyed only onversionName+versionCode— never saw the version change, so it skipped re-unpacking the newapp.zip. Bumpsserious_pythonto 4.3.4, which folds the APK'slastUpdateTimeinto that cache key so every (re)install re-extracts the current code while ordinary relaunches still hit the cache.flet build apkwas never affected (#6682) by @FeodorFitsner. - Fix an embedded
FletApp(an app rendered inside another Flet app — e.g. a preview or gallery host that runs example apps in-process) not refreshing its UI in response to events. Auto-update mode was tracked ascomponents_modeon a single process-globalcontextsingleton, so a host app that rendered viapage.render/page.render_viewsturned components mode on process-wide andcontext.auto_update_enabled()then returnedFalsefor the embedded app too — any handler that mutated a control without calling.update()(the common imperative style, including allpage.servicessensor readings) silently never re-rendered. Event dispatch also ran in a fresh task whose page context var could carry a different session's page, so context-derived state resolved against the wrong session.components_modeis now stored per-Session, andSession.dispatch_eventbinds the page context to its own session before invoking handlers, so multiple Flet apps sharing one process keep independent update behavior (#6699) by @FeodorFitsner. - Modernize examples for 0.86: replace the removed
TextField.error_textwitherror(chat tutorial,mind_queue,palette_editor), and declare the device permissions each sensor example needs to run on-device —NSMotionUsageDescriptionon iOS for the motion/barometer sensors andandroid.permission.VIBRATEfor HapticFeedback (#6699) by @FeodorFitsner. - Fix opening a
flet run --ios/--androidapp URL in a desktop browser: the page loaded but stayed on the boot screen, endlessly retrying a WebSocket connection tows://<host>:<port>/ws. Mobile-mode apps are mounted under a non-root path (e.g./counter/main.py), so the real WebSocket route lives at/counter/main.py/ws- but since 1.0 Alpha the FastAPI wrapper always passed the bare defaultwsendpoint name intoFletStaticFiles, bypassing its mount-path-aware fallback, andindex.htmlgot patched withflet.webSocketEndpoint="ws", which the web client resolves against the server root. The native iOS/Android client derives the path from the page URL and was unaffected. A relative WebSocket endpoint is now resolved against the app mount path when patchingindex.html, fixing browser access to any Flet web app mounted under a non-root path (--ios/--android,flet run --name, or aflet_web.fastapiapp mounted at a sub-path) (#6699) by @FeodorFitsner. - Fix web
RawImageandMatplotlibChartanimations flooding the console with uncatchable engine exceptions (and breaking the animation) after the browser tab was backgrounded for a while and then refocused. On Flet web the frame producer runs in a Pyodide worker (or on a remote server over a WebSocket) that the browser never throttles, while the client's Flutter frame pipeline is suspended whenever the tab is hidden - sosetStateschedules frames that never paint and the post-frame callbacks that dispose replacedui.Images never fire. Decoded images and pending disposals then pile up unbounded in the Dart heap and flush into the engine all at once on resume, one exception per queued frame. This is a client-side accumulation independent of transport, so it also affected native windows minimized with an animation running. Fixed in two layers: (1) a sharedFrameStreamVisibilityclient-side mixin - used by bothRawImageandflet-charts'MatplotlibChartCanvas- stops decoding/uploading and frees replaced images immediately while hidden (keeping only cheap offscreen state up to date, so incremental matplotlib diffs stay correct), then presents just the latest frame on resume; (2) a newpage.wait_until_visible()gate (driven byon_app_lifecycle_state_change, alongside apage.app_visibleproperty) that the streaming controls await internally, so producer loops park while hidden instead of rendering frames a suspended client can only discard (#6691) by @FeodorFitsner. - Fix
flet build/flet publishflooding non-interactive logs (CI, cloud build, any piped stdout) with thousands of progress-spinner frames, and fix the--no-rich-outputflag not actually producing plain output. The CLI's richConsolewas created withforce_terminal=Truewhenever theFLET_CLI_NO_RICH_OUTPUTenv var was unset, which forces theLivestatus spinner to repaint even when stdout isn't a TTY — so in a pipe every animation frame lands on its own line (e.g. hundreds of( ● ) Initializing web build...lines). And the--no-rich-outputCLI flag never reached that console at all: it's parsed per-command, after the module-levelconsoleis already built, so it only suppressed emojis while color and the spinner kept going. Now the console auto-detects the terminal (force_terminal=None) — interactive terminals keep the animated spinner while piped output stays quiet — and bothFLET_CLI_NO_RICH_OUTPUTand--no-rich-output(detected fromsys.argvat import) force fully plain output (#6704) by @FeodorFitsner.
Improvements
- Flutter updated to 3.44.7.
- Fix
flet_video.Videoresetting itsvolume(andpitch,playback_rate,shuffle_playlist,playlist_mode,subtitle_track) to the player's defaults after togglingvisibleoff then on — e.g.volumejumped back to100. Hiding aVideodisposes its nativemedia_kitplayer and showing it recreates a fresh one at default settings; the "last-applied" tracking now lives with the player (not the persistent control model) and is reset on recreation, sobuild()re-applies every setting to the new player (#6683, #6694) by @ndonkoHenri. - Fix
SearchBar.on_tap_outside_barnot firing when the user tapped outside the open search view. That case now has a dedicatedSearchBar.on_tap_outside_viewevent (fired when tapping outside the open view, e.g. to dismiss it), andon_tap_outside_baris documented to match what it actually does: fire while the bar is focused and the view is closed, likeTextField.on_tap_outside(#6593, #6697) by @ndonkoHenri. - Add a
--android-legacy-packagingflag (and[tool.flet.android].legacy_packagingsetting) toflet build apk/aabfor opting into legacy Android native-library packaging. By default (modern packaging), native.sofiles are stored uncompressed and page-aligned in the APK and memory-mapped directly at runtime, which typically gives a smaller install and Play Store download but a larger raw.apkfile. Enabling this option setsuseLegacyPackaging = trueso the.soare compressed inside the APK and extracted to disk on install: the raw.apkfile is smaller (handy when side-loading), at the cost of a larger on-device install and slower native-library loading. The extraction directory is exposed to Python asANDROID_NATIVE_LIBRARY_DIR, which can help custom native-library consumers that require a real filesystem path. See Native library packaging (#6698, #6703) by @FeodorFitsner.
- Fix code edits not taking effect under
-
0.86.117 Jul 2026Release notes
Open source →Improvements
flet-mcp'sget_apitool now covers top-level callables — the app entry point (run), reactive hooks (use_state,use_ref,use_effect, …), and decorators (component,memo,observable) — which previously returnednot foundbecause only classes were indexed. A newfunctionsbucket in the API builder extracts each package's re-exported public callables and renders them with asignature:line.get_apialso resolves enum member lookups inline:get_api("Colors", query="RED")now returns the matching members instead of erroring with a redirect tosearch_enum_members. Both changes remove wasted agent round-trips observed in production usage by @FeodorFitsner.
Bug fixes
- Fix
flet build windowsfailing on non-UTF-8 system locales (e.g. Simplified-Chinese Windows, code page 936/GBK) withwarning C4819escalated toerror C2220while compiling a plugin's Windows sources. A non-ASCII character in a plugin source (e.g. an em dash in a comment) couldn't be decoded under the system code page, and the build template's/WX(warnings-as-errors) turned it fatal. The Windows build template now compiles all targets with/utf-8, so every plugin — including third-party ones flet doesn't control (e.g.connectivity_plus) — reads its sources as UTF-8 regardless of the build machine's code page. Also bumpsserious_pythonto 4.3.3, which removes the character from its own plugin at the source (#6686) by @FeodorFitsner. - Fix the cryptic
shutil.ReadError: ... is not a zip filefailure in web apps when the app package download fails. The Pyodide worker piped thepyfetch(app_package_url)response straight intounpack_archive()without a status check, so any non-2xx response (transient server 500, expired auth 401, deleted app 404) wrote the JSON/HTML error body to a temp file and crashed while unpacking it. The worker now checksresponse.okand raises a readableFailed to download app package: HTTP <status> <url> — <body>error, including the first 200 chars of the error body. Applied to both the Flet web client and theflet buildtemplate (#6680) by @FeodorFitsner. - Remove unused
BasePagereturn type and import fromBaseControlandControlEvent(#6606) by @Iaw4tch. - Fix
GestureDetector.allowed_devicescrashing withtype 'List<dynamic>' is not a subtype of type 'List<String?>?'and preventing the control from rendering. Property values are deserialized from JSON asList<dynamic>, but the value was read viaget<List<String?>>(...), whose reified cast fails because aList<dynamic>is not aList<String?>. It's now read asList<dynamic>and each entry is converted to a string before parsing, restoringsupportedDevicesfiltering for Flutter'sGestureDetector(#6684) by @TURBODRIVER.
New Contributors
- @TURBODRIVER made their first contribution in #6684
Full Changelog: v0.86.0...v0.86.1
Release notes
Open source →Improvements
flet-mcp'sget_apitool now covers top-level callables — the app entry point (run), reactive hooks (use_state,use_ref,use_effect, …), and decorators (component,memo,observable) — which previously returnednot foundbecause only classes were indexed. A newfunctionsbucket in the API builder extracts each package's re-exported public callables and renders them with asignature:line.get_apialso resolves enum member lookups inline:get_api("Colors", query="RED")now returns the matching members instead of erroring with a redirect tosearch_enum_members. Both changes remove wasted agent round-trips observed in production usage (#6680) by @FeodorFitsner.
Bug fixes
- Fix
flet build windowsfailing on non-UTF-8 system locales (e.g. Simplified-Chinese Windows, code page 936/GBK) withwarning C4819escalated toerror C2220while compiling a plugin's Windows sources. A non-ASCII character in a plugin source (e.g. an em dash in a comment) couldn't be decoded under the system code page, and the build template's/WX(warnings-as-errors) turned it fatal. The Windows build template now compiles all targets with/utf-8, so every plugin — including third-party ones flet doesn't control (e.g.connectivity_plus) — reads its sources as UTF-8 regardless of the build machine's code page. Also bumpsserious_pythonto 4.3.3, which removes the character from its own plugin at the source (#6686) by @FeodorFitsner. - Fix the cryptic
shutil.ReadError: ... is not a zip filefailure in web apps when the app package download fails. The Pyodide worker piped thepyfetch(app_package_url)response straight intounpack_archive()without a status check, so any non-2xx response (transient server 500, expired auth 401, deleted app 404) wrote the JSON/HTML error body to a temp file and crashed while unpacking it. The worker now checksresponse.okand raises a readableFailed to download app package: HTTP <status> <url> — <body>error, including the first 200 chars of the error body. Applied to both the Flet web client and theflet buildtemplate (#6680) by @FeodorFitsner. - Remove unused
BasePagereturn type and import fromBaseControlandControlEvent(#6606) by @Iaw4tch. - Fix
GestureDetector.allowed_devicescrashing withtype 'List<dynamic>' is not a subtype of type 'List<String?>?'and preventing the control from rendering. Property values are deserialized from JSON asList<dynamic>, but the value was read viaget<List<String?>>(...), whose reified cast fails because aList<dynamic>is not aList<String?>. It's now read asList<dynamic>and each entry is converted to a string before parsing, restoringsupportedDevicesfiltering for Flutter'sGestureDetector(#6684) by @TURBODRIVER.
Release notes
Open source →No changes in the
fletDart package; version bumped for release coordination with the web client's readable app-package download errors (#6680). -
0.86.014 Jul 2026Release notes
Open source →New features
- Add support for Python
multiprocessingin packaged Flet desktop apps built withflet build macos,flet build windows, andflet build linux.multiprocessingAPIs such asProcess,ProcessPoolExecutor, thespawn/forkserverstart methods, and the resource tracker now work in packaged desktop apps. Previously, worker processes re-executedsys.executable, which pointed to the app binary itself, causing each worker to launch another GUI app instance and hang. Flet desktop runners now detect CPython multiprocessing child command lines before Flutter starts and divert them to a headless embedded Python interpreter viadart_bridge1.5.0+. The Python bootstrap also runs the app module as the realsys.modules["__main__"]withpython -msemantics, so top-level worker functions inmain.pycan be pickled correctly. When usingmultiprocessing, your app must follow normal Python multiprocessing rules: guardft.run(...)withif __name__ == "__main__":, define worker functions at module top level, and do not access Flet UI objects from worker processes. See the new Multiprocessing cookbook page. Mobile platforms remain unsupported because iOS and Android do not allow apps to spawn arbitrary child processes (#4283, #6577) by @ndonkoHenri. - Multi-version bundled CPython support in
flet buildandflet publish. Pick the runtime your app ships with via the new--python-versionflag (3.12 / 3.13 / 3.14), or let it be derived from[project].requires-pythonin yourpyproject.toml; defaults to the latest supported stable (currently 3.14). The matching CPython-standalone build, Pyodide release (0.27.7 / 0.29.4 / 314.0.1), and Emscripten wheel platform tag are all resolved fromflet-dev/python-build's date-keyed manifest. Adding a future pre-release CPython line (e.g. 3.15 beta) is a one-row append withprerelease=True— opt-in only via an explicit--python-version 3.15orrequires-python = "==3.15.*", never the auto-resolved default. Requiresserious_python>= 4.0.0, now pinned in theflet buildtemplate. See the new Choosing a Python version docs section (#6577) by @FeodorFitsner. - Add
ft.DataChannel: dedicated byte channels for widgets that move bulk binary data (image frames, audio buffers, ML tensors) between Dart and Python, bypassing the MsgPack control protocol. The Dart side opens a channel viaFletBackend.of(context).openDataChannel()and announces it to Python by firing adata_channel_opencontrol event with{channel_name, channel_id}; the Python side declareson_data_channel_open: Optional[ft.EventHandler[ft.DataChannelOpenEvent]]and captures the channel viaself.get_data_channel(e.channel_id). Backed by a dedicatedPythonBridgeper channel in embedded native mode (4–7 GiB/s on M2 Pro) and by the defaultProtocolMuxedDataChannelFactoryin dev / web modes (raw-byte frames muxed over the active Flet protocol transport with a 1-byte type discriminator). Pyodide gets zero-copy outbound sends viapostMessageTransferable ArrayBuffer. First consumer:flet-chartsMatplotlibChartCanvas, migrated from_invoke_methodPNG dispatch to a 1-byte-opcode data channel by @FeodorFitsner. - In-process Python transport (
dart_bridgeFFI).package:fletgains a third protocol transport alongside the UDS / TCP socket servers: it can run Flet's MsgPack protocol over an in-processdart_bridgebyte channel via aFletApp(channelBuilder: …)seam (thefletpackage stays Python-independent — it doesn't depend onserious_pythonor know aboutPythonBridge; the embedder wires the channel).serious_python>= 3.0.0 uses this seam to embed the Python interpreter in-process instead of talking to it over a localhost socket, and theflet buildtemplate migrates from sockets to the FFI transport. On Android, where the OS may keep the process alive across a back-button quit and restart only the Dart VM, the transport rebinds to the new VM'sdart_bridgeports on a session-restart signal (libdart_bridge>= 1.3.0) — the Python process and its in-memory state are preserved and the Flet session is rebuilt fromREGISTER_CLIENTby @FeodorFitsner. - Add
flet cleancommand that deletes thebuilddirectory of a Flet app — the Flutter bootstrap project, cached artifacts, and generated output — in a single step (#6233) by @ndonkoHenri. - Add
compression_qualitytoFilePicker.pick_files()for selecting the image compression quality used by supported platforms (#6573) by @ndonkoHenri. - Add
ConsentManagertoflet-adsfor gathering user consent (e.g. GDPR/EEA) via Google's User Messaging Platform (UMP) before requesting ads (#6569, #6615) by @ndonkoHenri. - Add
ft.RawImage: a high-bandwidth pixel-frame display control for Pillow output, NumPy arrays, camera frames and procedural graphics. Frames stream over a dedicatedft.DataChannelinstead of the control protocol: raw premultiplied RGBA straight to a GPU texture on local transports (desktop,flet run, Pyodide), automatic PNG fallback on remoteflet-websessions. The awaitablerender(pil_or_numpy)/render_rgba(w, h, bytes)/render_encoded(png_jpeg_webp_bytes)methods resolve when the client has displayed the frame, so a plainwhile True: await ri.render(...)loop self-paces to display speed. Premultiplied-alpha conversion runs in Pillow's C loops with an opaque fast-path; Pillow and NumPy remain optional. The last frame is retained and replayed on remount, mirroringImage.src. Ships with five gallery examples (photo viewer, plasma, Pillow paint, Mandelbrot explorer, Game of Life) and a docs page withRawImagevsImageguidance (#6674) by @FeodorFitsner.
Improvements
- Swift Package Manager for iOS/macOS builds (on by default).
flet build/flet debugnow integrate the embedded Python runtime via SPM instead of CocoaPods (CocoaPods goes read-only in December 2026). Flet auto-falls back to CocoaPods when the app depends on a package that isn't SPM-ready — currentlyflet-video(media_kit) — since Flutter then builds the whole app with CocoaPods. Force CocoaPods for other non-SPM packages with--no-swift-package-manager(orswift_package_manager = falseunder[tool.flet]). Flet does not change Flutter's global SPM configuration; the setting only selects howserious_pythonstages the runtime to match. When SPM is used (it has nopod installhook),flet buildsetsSERIOUS_PYTHON_DARWIN_SPMsoserious_python'spackagestep stages the runtime (Python/dart_bridge xcframeworks, the iOS native extensions, and the stdlib/site-packages/app resources) into the plugin'sPackage.swiftlayout on the host beforeflutter build, and exports theSP_NATIVE_SETcache-bust key into the build. Requires the SPM-capableserious_pythonrelease. - Smaller Android apps with no native-packaging config.
flet build apk/aabconsume serious_python's new Android packaging: Python extension modules load memory-mapped directly from the APK (no extraction to disk), and pure Python ships in stored asset zips read viazipimport, so the standard library is no longer duplicated per ABI. Apps no longer needuseLegacyPackaging/keepDebugSymbols— theflet buildAndroid template drops them; just useminSdk 23+. New--android-extract-packagesflag and[tool.flet.android].extract_packagesship "path-hungry" packages — those that read bundled data via__file__/pkg_resourcesinstead ofimportlib.resources— extracted to disk instead of inside the zip (most packages, includingcertifi, are zip-safe and need no entry). Requiresserious_pythonwith the native-mmap packaging (dart_bridge 1.4.0). - Pyodide is no longer pre-baked into the
flet buildtemplate. Eachflet build web/flet publishrun downloads the matchingpyodide-core-<version>.tar.bz2(plus the runtimemicropipandpackagingwheels) into a per-version cache at~/.flet/pyodide/<version>/and copies the files into the build output. Subsequent builds reuse the cache; the older0.27.5bundle previously shipped in the cookiecutter template is gone (#6577) by @FeodorFitsner. - The supported Python / Pyodide / dart_bridge versions are loaded on demand from
flet-dev/python-build's date-keyedmanifest.json(fetched once and cached under~/.flet/cache), the single source of truth shared withserious_python— replacing flet's hand-mirrored version table.flet buildforwards onlySERIOUS_PYTHON_VERSIONand letsserious_pythonderive the full version / build date / dart_bridge version from its own committed snapshot. The module exposesget_supported_python_versions()/get_default_python_version()(the previousSUPPORTED_PYTHON_VERSIONS/DEFAULT_PYTHON_VERSIONconstants are removed) (#6577) by @FeodorFitsner. flet --versionshows just the Flet and Flutter versions; the staticPyodide: …line and the globalflet.version.pyodide_versionexport are removed (the supported Python / Pyodide set now lives in python-build's manifest, not the CLI output) (#6577) by @FeodorFitsner.flet --version --jsonemits a machine-readable document — Flet/Flutter versions and the Linux build dependencies — for CI to read viajqinstead of importing Flet internals withpython -c. (The supported Python/Pyodide table is no longer included; it comes from python-build's manifest.) The canonical Linux apt dependency list moved fromflet.utils.linux_deps(runtime package) toflet_cli.utils.linux_deps(build tooling) by @FeodorFitsner.client/web/python.jsand the build template'spython.jsno longer hardcodedefaultPyodideUrl.patch_index.pynow injectsflet.pyodideUrlper build (CDN URL by default, or the localpyodide/pyodide.jspath under--no-cdn) so the runtime URL always tracks the resolved Pyodide release (#6577) by @FeodorFitsner.- Stream-oriented Flet protocol transports (UDS / TCP used by
flet rundev mode) now use length-prefixed framing instead of streamingmsgpack.Unpacker.feed. Combined with a new 1-byte type discriminator at the head of every packet (0x00= MsgPack control frame,0x01= raw DataChannel frame), this unifies framing across all transports (sockets, WebSocket,dart_bridgeFFI, PyodidepostMessage).StreamingMsgpackDeserializeris removed frompackage:flet; each inbound packet is one complete MsgPack value, decoded one-shot viamsgpack.deserialize(bytes)by @FeodorFitsner. - Bump the bundled Flutter to 3.44.2 (from 3.41.7). The Flet client and the
flet buildtemplate migrate to Flutter 3.44's built-in Kotlin (the Android app no longer applies the Kotlin Gradle plugin itself) and Java 17; the client's Gradle wrapper moves to 8.14 by @FeodorFitsner. - Raw RGBA Matplotlib frames on local transports.
MatplotlibChartnow skips per-frame diffing and PNG encode/decode when the client runs on the same machine: uncompressed RGBA full frames stream straight from Agg's buffer over the chart'sDataChannel(new0x04opcode) and are displayed with a singledecodeImageFromPixels+ swap on the Dart side. A 1600×1000 @ DPR 2 figure (24 MB/frame) over a local socket goes from 7.4 to 18.7 fps, leaving matplotlib's own render as the dominant per-frame cost; remote WebSocket clients keep the compact PNG full+diff pipeline. The format is auto-selected via the newConnection.local_data_transportcapability flag (set by the socket,dart_bridgeand Pyodide transports). Also fixes O(n²) length-prefixed packet reassembly in the Dart socket transport — multi-MB frames arrive in dozens of chunks and previously re-flattened the accumulation buffer on every chunk (#6673) by @FeodorFitsner. flet build webandflet publishnow default the web renderer tocanvaskitinstead ofauto. Withauto, Chromium selects the dart2wasm/skwasm renderer, whose JS↔Dart typed-data boundary costs make byte-streaming Pyodide apps (matplotlib frames,RawImage) ~6–7x slower per frame; pass--renderer autoor set[tool.flet.web].rendererto restore the old behavior. Also fixestool.flet.web.rendererbeing ignored byflet publish(shadowed by an argparse default) (#6673) by @FeodorFitsner.- Faster mobile cold start:
import fletis now lazy. Thefletpackage previously executed its full ~270-module public API eagerly onimport flet; it now resolves public names on first access via a module-level__getattr__(PEP 562), so an app loads only the modules it actually uses. On a mid-range Android device this cutimport fletfrom ~2.0s to ~0.15s. The eager subsystem clusters thatPagepulled in (auth, components/hooks, Cupertino controls) are deferred too. Type checkers, IDEs, andfrom flet import *are unaffected (#6597) by @FeodorFitsner.
Breaking changes
- App files now ship unpacked in a read-only bundle, and the storage directories were reworked (requires
serious_python>= 4.0.0, now pinned in theflet buildtemplate). Your Python sources ship unpacked inside the app bundle next to the stdlib/site-packages (no first-launchapp.zipextraction) on macOS/iOS/Windows/Linux; on Android they ship as a storedapp.zipasset unpacked once on first launch; web is unchanged. The app directory is now read-only, so the Python program's working directory moved to a writable, app-private data dir.FLET_APP_STORAGE_DATAnow maps to the OS application support dir (adatasubdir) instead of the user's Documents folder and is the cwd;FLET_APP_STORAGE_TEMPnow points to the OS temp dir (was the cache dir) and a newFLET_APP_STORAGE_CACHEexposes the cache dir.flet runsets the dev cwd to a hidden, git-ignored<project>/.flet/storage/data. Relative reads of bundled files (open("seed.json")) must move to__file__/importlib.resourcesorassets/. See the app files unpacked / storage dirs guide by @FeodorFitsner. flet buildandflet publishnow bundle CPython 3.14 by default (previously 3.12, implicit via the old single-versionserious_python). Existing apps that depend on native wheels without 3.14 binaries should pin explicitly with--python-version 3.12(CLI),requires-python = ">=3.12,<3.13"(pyproject), orSERIOUS_PYTHON_VERSION=3.12in the build environment (#6577) by @FeodorFitsner.- Android builds now include only the ABIs the bundled Python supports, sourced per-version from python-build's manifest (
pythons.<short>.android_abis) rather than hardcoded in flet. As of python-build20260630,armeabi-v7a(32-bit ARM) is published for 3.12, 3.13 and 3.14, so all three build it by default; an explicit--arch <abi>is validated against the selected Python's supported set and fails with a clear error otherwise (#6578) by @ndonkoHenri. flet build/flet publishnow compile your app and packages to.pycby default (previously off). This removes per-launch bytecode recompilation — a significant cold-start win, especially on mobile where pure Python is imported from a stored zip (zipimport) and can't cache bytecode back to disk, so every module would otherwise recompile from source on each launch. The CLI flags gain--no-compile-app/--no-compile-packages(viaargparse.BooleanOptionalAction; the existing--compile-app/--compile-packagesstill work), and[tool.flet.compile].app/.packagesnow default totrue. Pass--no-compile-*or set them tofalseto restore the old behavior (faster iterative builds, or keeping.pysource in the bundle). Compiled web builds were verified to load in Pyodide (bundled CPython and Pyodide share the same minor version). See the compile-on-by-default guide (#6598) by @FeodorFitsner.- Flet protocol wire format on stream-oriented transports (UDS / TCP) is incompatible with pre-0.86 servers and clients. Every packet now starts with a 4-byte little-endian length prefix and a 1-byte type discriminator (
0x00= MsgPack control frame,0x01= raw DataChannel frame). WebSocket /postMessage/dart_bridgetransports keep native message boundaries and only gain the type byte. The Flet CLI dev server and the in-process Python runtime are upgraded in lockstep — runningflet runwith mismatchedfletversions across CLI and runtime is no longer supported. See the DataChannel protocol framing upgrade guide. TheMatplotlibChartCanvaswidget transports its full / diff / clear frames via aDataChannelrather than_invoke_methodarguments — visually identical, but custom code that subclassed it and overrode the apply methods may need updating by @FeodorFitsner.
Deprecations
- Deprecate the
--clear-cacheflag offlet buildandflet debug; use the newflet cleancommand instead. The flag remains functional but now emits a deprecation warning, and is scheduled for removal in0.89.0(#6233) by @ndonkoHenri.
Bug fixes
- Fix a debug-mode
'!_dirty': is not trueassertion (EXCEPTION CAUGHT BY WIDGETS LIBRARYin_BootOverlay) thrown by apps built or debugged from theflet buildtemplate when the app becomes ready. With the defaultboot_screen.fade_out_durationof 0 the overlay's zero-durationAnimatedOpacitycompleted synchronously, firingonEnd— and itssetState— in the middle of the overlay's own rebuild. The overlay is now removed in a single state update when no fade is configured; non-zero fade durations still animate as before. Debug-mode only: the assertion is compiled out of release builds (#6666) by @FeodorFitsner. - Fix
flet buildfailing on Windows when a dependency is pulled in via[tool.flet.<platform>].dev_packages(or any local-path install): the rewritten<pkg> @ file://<path>URL now usesPath.as_uri(), producing the correctfile:///D:/...three-slash form instead offile://D:\..., which pip on Windows parsed as a UNC path and aborted withOSError: [Errno 2] No such file or directory: '\\\\D:\\a\\...'(#6577) by @FeodorFitsner. - Fix
flet build web --python-version 3.13failing to match any Pyodide-built native wheel. The 3.13 row in the Python version registry was set to Pyodide platform tagpyodide-2025.0-wasm32, but Pyodide actually publishes 0.29 wheels underpyemscripten_2025_0_wasm32(thepyodide_→pyemscripten_prefix transition happened at 0.28/0.29, not at 314.0). Corrected topyemscripten-2025.0-wasm32so pip's wheel selection picks up the correct tags by @FeodorFitsner. flet buildnow cleans the build directory when the bundled Python version changes between builds, preventing stale compiled bytecode from the previous version crashing the app at runtime withImportError: bad magic numberby @FeodorFitsner.- Fix locating Flet controls by their user-assigned
keyin tests.ValueKey(control.key)was constructed asValueKey<Object>, and Flutter's runtimeType-strictValueKey.==never matches that against theValueKey<String>the rendered widget carries — sofind.byKey(Key('foo'))(flutter_test) andfind_by_key('foo')(Flet tester) located 0 widgets. TheValueKeyis now built with the value's concrete type (String →ValueKey<String>, int →ValueKey<int>, …) on both the Dart and Python sides by @FeodorFitsner. - Fix
flet build apk/flet build aabwith--archpackaging native libraries for all Android ABIs instead of only the requested ones. The requested architectures are now forwarded to Flutter as--target-platform(so--split-per-abibuilds only the requested splits), unrequested ABI directories are excluded from the artifact viapackaging.jniLibs.excludes, Android--archvalues are validated against the bundled Python's supported ABIs, multiple--archvalues now correctly reachserious_python(comma-joined), and stale artifacts from previous builds are no longer copied into the output directory (#6567, #6578) by @ndonkoHenri. - Fix repeated
--arch,--source-packagesand--permissionsflags inflet buildkeeping only the values of the last occurrence (action="extend"on each) (#6578) by @ndonkoHenri. - Fix
flet build apkfailing atmergeDebugNativeLibswithN files found with path 'lib/<abi>/libc++_shared.so'when an app combinesserious_python_androidwith another Flutter plugin that also bundles the NDK C++ runtime (#6570, #6571) by @ndonkoHenri. - Specify
handlersignatures insubscribeandsubscribe_topicmethods ofPubSubClientfor better type checking (#6549) by @Iaw4tch - Fix
FilePicker.pick_files()on web for slow network shares or slow machines: passcancel_upload_on_window_blur=Falseto prevent valid file selections from being reported as cancelled when the browser window loses focus during file picking (#771, #6573) by @ndonkoHenri. - Support
PagePlatform.ANDROID_TVinPage.get_device_info()retrieval (#6604) by @bl1nch. - Fix
ProgressRing.year_2023being ignored, so the control correctly switches between the latest and 2023 Material Design appearances (#6614) by @ndonkoHenri. flet build ipa/iosapps that ship ctypes packages with plain.dylibshared libraries (e.g.llama-cpp-python) now load them on the iOS simulator instead of failing at launch with adlopenplatform mismatch (have 'iOS', need 'iOS-simulator'); the iOS runtime also now bundles the_multiprocessingextension (importable, not spawnable). Bumps the pinned bundle toserious_python4.2.1 / python-build20260701(serious_python#223) by @ndonkoHenri, @FeodorFitsner.- Improve performance of checking added/removed controls in Session.patch_control from O(N²) to O(N) (#6651) by @davidlawson.
- Fix stateful controls inside
ResponsiveRow(video players, WebViews, scroll positions) losing their state whenever a window resize crossed a breakpoint and the layout switched between a single row and wrapping (#6661, #6663) by @FeodorFitsner.
Documentation
- Improve
FilePicker.save_file()documentation: on desktop, passingsrc_byteswrites those bytes to the selected file (#6573) by @ndonkoHenri.
New Contributors
- @EH-MLS made their first contribution in #6591
- @Iaw4tch made their first contribution in #6564
- @Federicorao made their first contribution in #6582
- @xiaocai2011 made their first contribution in #6617
- @davidlawson made their first contribution in #6651
Full Changelog: v0.85.3...v0.86.0
Release notes
Open source →New features
- Add support for Python
multiprocessingin packaged Flet desktop apps built withflet build macos,flet build windows, andflet build linux.multiprocessingAPIs such asProcess,ProcessPoolExecutor, thespawn/forkserverstart methods, and the resource tracker now work in packaged desktop apps. Previously, worker processes re-executedsys.executable, which pointed to the app binary itself, causing each worker to launch another GUI app instance and hang. Flet desktop runners now detect CPython multiprocessing child command lines before Flutter starts and divert them to a headless embedded Python interpreter viadart_bridge1.5.0+. The Python bootstrap also runs the app module as the realsys.modules["__main__"]withpython -msemantics, so top-level worker functions inmain.pycan be pickled correctly. When usingmultiprocessing, your app must follow normal Python multiprocessing rules: guardft.run(...)withif __name__ == "__main__":, define worker functions at module top level, and do not access Flet UI objects from worker processes. See the new Multiprocessing cookbook page. Mobile platforms remain unsupported because iOS and Android do not allow apps to spawn arbitrary child processes (#4283, #6577) by @ndonkoHenri. - Multi-version bundled CPython support in
flet buildandflet publish. Pick the runtime your app ships with via the new--python-versionflag (3.12 / 3.13 / 3.14), or let it be derived from[project].requires-pythonin yourpyproject.toml; defaults to the latest supported stable (currently 3.14). The matching CPython-standalone build, Pyodide release (0.27.7 / 0.29.4 / 314.0.1), and Emscripten wheel platform tag are all resolved fromflet-dev/python-build's date-keyed manifest. Adding a future pre-release CPython line (e.g. 3.15 beta) is a one-row append withprerelease=True— opt-in only via an explicit--python-version 3.15orrequires-python = "==3.15.*", never the auto-resolved default. Requiresserious_python>= 4.0.0, now pinned in theflet buildtemplate. See the new Choosing a Python version docs section (#6577) by @FeodorFitsner. - Add
ft.DataChannel: dedicated byte channels for widgets that move bulk binary data (image frames, audio buffers, ML tensors) between Dart and Python, bypassing the MsgPack control protocol. The Dart side opens a channel viaFletBackend.of(context).openDataChannel()and announces it to Python by firing adata_channel_opencontrol event with{channel_name, channel_id}; the Python side declareson_data_channel_open: Optional[ft.EventHandler[ft.DataChannelOpenEvent]]and captures the channel viaself.get_data_channel(e.channel_id). Backed by a dedicatedPythonBridgeper channel in embedded native mode (4–7 GiB/s on M2 Pro) and by the defaultProtocolMuxedDataChannelFactoryin dev / web modes (raw-byte frames muxed over the active Flet protocol transport with a 1-byte type discriminator). Pyodide gets zero-copy outbound sends viapostMessageTransferable ArrayBuffer. First consumer:flet-chartsMatplotlibChartCanvas, migrated from_invoke_methodPNG dispatch to a 1-byte-opcode data channel (#6601) by @FeodorFitsner. - In-process Python transport (
dart_bridgeFFI).package:fletgains a third protocol transport alongside the UDS / TCP socket servers: it can run Flet's MsgPack protocol over an in-processdart_bridgebyte channel via aFletApp(channelBuilder: …)seam (thefletpackage stays Python-independent — it doesn't depend onserious_pythonor know aboutPythonBridge; the embedder wires the channel).serious_python>= 3.0.0 uses this seam to embed the Python interpreter in-process instead of talking to it over a localhost socket, and theflet buildtemplate migrates from sockets to the FFI transport. On Android, where the OS may keep the process alive across a back-button quit and restart only the Dart VM, the transport rebinds to the new VM'sdart_bridgeports on a session-restart signal (libdart_bridge>= 1.3.0) — the Python process and its in-memory state are preserved and the Flet session is rebuilt fromREGISTER_CLIENT(#6601) by @FeodorFitsner. - Add
flet cleancommand that deletes thebuilddirectory of a Flet app — the Flutter bootstrap project, cached artifacts, and generated output — in a single step (#6233) by @ndonkoHenri. - Add
compression_qualitytoFilePicker.pick_files()for selecting the image compression quality used by supported platforms (#6573) by @ndonkoHenri. - Add
ConsentManagertoflet-adsfor gathering user consent (e.g. GDPR/EEA) via Google's User Messaging Platform (UMP) before requesting ads (#6569, #6615) by @ndonkoHenri. - Add
ft.RawImage: a high-bandwidth pixel-frame display control for Pillow output, NumPy arrays, camera frames and procedural graphics. Frames stream over a dedicatedft.DataChannelinstead of the control protocol: raw premultiplied RGBA straight to a GPU texture on local transports (desktop,flet run, Pyodide), automatic PNG fallback on remoteflet-websessions. The awaitablerender(pil_or_numpy)/render_rgba(w, h, bytes)/render_encoded(png_jpeg_webp_bytes)methods resolve when the client has displayed the frame, so a plainwhile True: await ri.render(...)loop self-paces to display speed. Premultiplied-alpha conversion runs in Pillow's C loops with an opaque fast-path; Pillow and NumPy remain optional. The last frame is retained and replayed on remount, mirroringImage.src. Ships with five gallery examples (photo viewer, plasma, Pillow paint, Mandelbrot explorer, Game of Life) and a docs page withRawImagevsImageguidance (#6674) by @FeodorFitsner.
Improvements
- Swift Package Manager for iOS/macOS builds (on by default).
flet build/flet debugnow integrate the embedded Python runtime via SPM instead of CocoaPods (CocoaPods goes read-only in December 2026). Flet auto-falls back to CocoaPods when the app depends on a package that isn't SPM-ready — currentlyflet-video(media_kit) — since Flutter then builds the whole app with CocoaPods. Force CocoaPods for other non-SPM packages with--no-swift-package-manager(orswift_package_manager = falseunder[tool.flet]). Flet does not change Flutter's global SPM configuration; the setting only selects howserious_pythonstages the runtime to match. When SPM is used (it has nopod installhook),flet buildsetsSERIOUS_PYTHON_DARWIN_SPMsoserious_python'spackagestep stages the runtime (Python/dart_bridge xcframeworks, the iOS native extensions, and the stdlib/site-packages/app resources) into the plugin'sPackage.swiftlayout on the host beforeflutter build, and exports theSP_NATIVE_SETcache-bust key into the build. Requires the SPM-capableserious_pythonrelease (#6608). - Smaller Android apps with no native-packaging config.
flet build apk/aabconsume serious_python's new Android packaging: Python extension modules load memory-mapped directly from the APK (no extraction to disk), and pure Python ships in stored asset zips read viazipimport, so the standard library is no longer duplicated per ABI. Apps no longer needuseLegacyPackaging/keepDebugSymbols— theflet buildAndroid template drops them; just useminSdk 23+. New--android-extract-packagesflag and[tool.flet.android].extract_packagesship "path-hungry" packages — those that read bundled data via__file__/pkg_resourcesinstead ofimportlib.resources— extracted to disk instead of inside the zip (most packages, includingcertifi, are zip-safe and need no entry). Requiresserious_pythonwith the native-mmap packaging (dart_bridge 1.4.0) (#6601). - Pyodide is no longer pre-baked into the
flet buildtemplate. Eachflet build web/flet publishrun downloads the matchingpyodide-core-<version>.tar.bz2(plus the runtimemicropipandpackagingwheels) into a per-version cache at~/.flet/pyodide/<version>/and copies the files into the build output. Subsequent builds reuse the cache; the older0.27.5bundle previously shipped in the cookiecutter template is gone (#6577) by @FeodorFitsner. - The supported Python / Pyodide / dart_bridge versions are loaded on demand from
flet-dev/python-build's date-keyedmanifest.json(fetched once and cached under~/.flet/cache), the single source of truth shared withserious_python— replacing flet's hand-mirrored version table.flet buildforwards onlySERIOUS_PYTHON_VERSIONand letsserious_pythonderive the full version / build date / dart_bridge version from its own committed snapshot. The module exposesget_supported_python_versions()/get_default_python_version()(the previousSUPPORTED_PYTHON_VERSIONS/DEFAULT_PYTHON_VERSIONconstants are removed) (#6577) by @FeodorFitsner. flet --versionshows just the Flet and Flutter versions; the staticPyodide: …line and the globalflet.version.pyodide_versionexport are removed (the supported Python / Pyodide set now lives in python-build's manifest, not the CLI output) (#6577) by @FeodorFitsner.flet --version --jsonemits a machine-readable document — Flet/Flutter versions and the Linux build dependencies — for CI to read viajqinstead of importing Flet internals withpython -c. (The supported Python/Pyodide table is no longer included; it comes from python-build's manifest.) The canonical Linux apt dependency list moved fromflet.utils.linux_deps(runtime package) toflet_cli.utils.linux_deps(build tooling) (#6601) by @FeodorFitsner.client/web/python.jsand the build template'spython.jsno longer hardcodedefaultPyodideUrl.patch_index.pynow injectsflet.pyodideUrlper build (CDN URL by default, or the localpyodide/pyodide.jspath under--no-cdn) so the runtime URL always tracks the resolved Pyodide release (#6577) by @FeodorFitsner.- Stream-oriented Flet protocol transports (UDS / TCP used by
flet rundev mode) now use length-prefixed framing instead of streamingmsgpack.Unpacker.feed. Combined with a new 1-byte type discriminator at the head of every packet (0x00= MsgPack control frame,0x01= raw DataChannel frame), this unifies framing across all transports (sockets, WebSocket,dart_bridgeFFI, PyodidepostMessage).StreamingMsgpackDeserializeris removed frompackage:flet; each inbound packet is one complete MsgPack value, decoded one-shot viamsgpack.deserialize(bytes)(#6601) by @FeodorFitsner. - Bump the bundled Flutter to 3.44.2 (from 3.41.7). The Flet client and the
flet buildtemplate migrate to Flutter 3.44's built-in Kotlin (the Android app no longer applies the Kotlin Gradle plugin itself) and Java 17; the client's Gradle wrapper moves to 8.14 (#6601) by @FeodorFitsner. - Raw RGBA Matplotlib frames on local transports.
MatplotlibChartnow skips per-frame diffing and PNG encode/decode when the client runs on the same machine: uncompressed RGBA full frames stream straight from Agg's buffer over the chart'sDataChannel(new0x04opcode) and are displayed with a singledecodeImageFromPixels+ swap on the Dart side. A 1600×1000 @ DPR 2 figure (24 MB/frame) over a local socket goes from 7.4 to 18.7 fps, leaving matplotlib's own render as the dominant per-frame cost; remote WebSocket clients keep the compact PNG full+diff pipeline. The format is auto-selected via the newConnection.local_data_transportcapability flag (set by the socket,dart_bridgeand Pyodide transports). Also fixes O(n²) length-prefixed packet reassembly in the Dart socket transport — multi-MB frames arrive in dozens of chunks and previously re-flattened the accumulation buffer on every chunk (#6673) by @FeodorFitsner. flet build webandflet publishnow default the web renderer tocanvaskitinstead ofauto. Withauto, Chromium selects the dart2wasm/skwasm renderer, whose JS↔Dart typed-data boundary costs make byte-streaming Pyodide apps (matplotlib frames,RawImage) ~6–7x slower per frame; pass--renderer autoor set[tool.flet.web].rendererto restore the old behavior. Also fixestool.flet.web.rendererbeing ignored byflet publish(shadowed by an argparse default) (#6673) by @FeodorFitsner.- Faster mobile cold start:
import fletis now lazy. Thefletpackage previously executed its full ~270-module public API eagerly onimport flet; it now resolves public names on first access via a module-level__getattr__(PEP 562), so an app loads only the modules it actually uses. On a mid-range Android device this cutimport fletfrom ~2.0s to ~0.15s. The eager subsystem clusters thatPagepulled in (auth, components/hooks, Cupertino controls) are deferred too. Type checkers, IDEs, andfrom flet import *are unaffected (#6597) by @FeodorFitsner.
Breaking changes
- App files now ship unpacked in a read-only bundle, and the storage directories were reworked (requires
serious_python>= 4.0.0, now pinned in theflet buildtemplate). Your Python sources ship unpacked inside the app bundle next to the stdlib/site-packages (no first-launchapp.zipextraction) on macOS/iOS/Windows/Linux; on Android they ship as a storedapp.zipasset unpacked once on first launch; web is unchanged. The app directory is now read-only, so the Python program's working directory moved to a writable, app-private data dir.FLET_APP_STORAGE_DATAnow maps to the OS application support dir (adatasubdir) instead of the user's Documents folder and is the cwd;FLET_APP_STORAGE_TEMPnow points to the OS temp dir (was the cache dir) and a newFLET_APP_STORAGE_CACHEexposes the cache dir.flet runsets the dev cwd to a hidden, git-ignored<project>/.flet/storage/data. Relative reads of bundled files (open("seed.json")) must move to__file__/importlib.resourcesorassets/. See the app files unpacked / storage dirs guide (#6608) by @FeodorFitsner. flet buildandflet publishnow bundle CPython 3.14 by default (previously 3.12, implicit via the old single-versionserious_python). Existing apps that depend on native wheels without 3.14 binaries should pin explicitly with--python-version 3.12(CLI),requires-python = ">=3.12,<3.13"(pyproject), orSERIOUS_PYTHON_VERSION=3.12in the build environment (#6577) by @FeodorFitsner.- Android builds now include only the ABIs the bundled Python supports, sourced per-version from python-build's manifest (
pythons.<short>.android_abis) rather than hardcoded in flet. As of python-build20260630,armeabi-v7a(32-bit ARM) is published for 3.12, 3.13 and 3.14, so all three build it by default; an explicit--arch <abi>is validated against the selected Python's supported set and fails with a clear error otherwise (#6578) by @ndonkoHenri. flet build/flet publishnow compile your app and packages to.pycby default (previously off). This removes per-launch bytecode recompilation — a significant cold-start win, especially on mobile where pure Python is imported from a stored zip (zipimport) and can't cache bytecode back to disk, so every module would otherwise recompile from source on each launch. The CLI flags gain--no-compile-app/--no-compile-packages(viaargparse.BooleanOptionalAction; the existing--compile-app/--compile-packagesstill work), and[tool.flet.compile].app/.packagesnow default totrue. Pass--no-compile-*or set them tofalseto restore the old behavior (faster iterative builds, or keeping.pysource in the bundle). Compiled web builds were verified to load in Pyodide (bundled CPython and Pyodide share the same minor version). See the compile-on-by-default guide (#6598) by @FeodorFitsner.- Flet protocol wire format on stream-oriented transports (UDS / TCP) is incompatible with pre-0.86 servers and clients. Every packet now starts with a 4-byte little-endian length prefix and a 1-byte type discriminator (
0x00= MsgPack control frame,0x01= raw DataChannel frame). WebSocket /postMessage/dart_bridgetransports keep native message boundaries and only gain the type byte. The Flet CLI dev server and the in-process Python runtime are upgraded in lockstep — runningflet runwith mismatchedfletversions across CLI and runtime is no longer supported. See the DataChannel protocol framing upgrade guide. TheMatplotlibChartCanvaswidget transports its full / diff / clear frames via aDataChannelrather than_invoke_methodarguments — visually identical, but custom code that subclassed it and overrode the apply methods may need updating (#6601) by @FeodorFitsner.
Deprecations
- Deprecate the
--clear-cacheflag offlet buildandflet debug; use the newflet cleancommand instead. The flag remains functional but now emits a deprecation warning, and is scheduled for removal in0.89.0(#6233) by @ndonkoHenri.
Bug fixes
- Fix a debug-mode
'!_dirty': is not trueassertion (EXCEPTION CAUGHT BY WIDGETS LIBRARYin_BootOverlay) thrown by apps built or debugged from theflet buildtemplate when the app becomes ready. With the defaultboot_screen.fade_out_durationof 0 the overlay's zero-durationAnimatedOpacitycompleted synchronously, firingonEnd— and itssetState— in the middle of the overlay's own rebuild. The overlay is now removed in a single state update when no fade is configured; non-zero fade durations still animate as before. Debug-mode only: the assertion is compiled out of release builds (#6666) by @FeodorFitsner. - Fix
flet buildfailing on Windows when a dependency is pulled in via[tool.flet.<platform>].dev_packages(or any local-path install): the rewritten<pkg> @ file://<path>URL now usesPath.as_uri(), producing the correctfile:///D:/...three-slash form instead offile://D:\..., which pip on Windows parsed as a UNC path and aborted withOSError: [Errno 2] No such file or directory: '\\\\D:\\a\\...'(#6577) by @FeodorFitsner. - Fix
flet build web --python-version 3.13failing to match any Pyodide-built native wheel. The 3.13 row in the Python version registry was set to Pyodide platform tagpyodide-2025.0-wasm32, but Pyodide actually publishes 0.29 wheels underpyemscripten_2025_0_wasm32(thepyodide_→pyemscripten_prefix transition happened at 0.28/0.29, not at 314.0). Corrected topyemscripten-2025.0-wasm32so pip's wheel selection picks up the correct tags (#6601) by @FeodorFitsner. flet buildnow cleans the build directory when the bundled Python version changes between builds, preventing stale compiled bytecode from the previous version crashing the app at runtime withImportError: bad magic number(#6601) by @FeodorFitsner.- Fix locating Flet controls by their user-assigned
keyin tests.ValueKey(control.key)was constructed asValueKey<Object>, and Flutter's runtimeType-strictValueKey.==never matches that against theValueKey<String>the rendered widget carries — sofind.byKey(Key('foo'))(flutter_test) andfind_by_key('foo')(Flet tester) located 0 widgets. TheValueKeyis now built with the value's concrete type (String →ValueKey<String>, int →ValueKey<int>, …) on both the Dart and Python sides (#6601) by @FeodorFitsner. - Fix
flet build apk/flet build aabwith--archpackaging native libraries for all Android ABIs instead of only the requested ones. The requested architectures are now forwarded to Flutter as--target-platform(so--split-per-abibuilds only the requested splits), unrequested ABI directories are excluded from the artifact viapackaging.jniLibs.excludes, Android--archvalues are validated against the bundled Python's supported ABIs, multiple--archvalues now correctly reachserious_python(comma-joined), and stale artifacts from previous builds are no longer copied into the output directory (#6567, #6578) by @ndonkoHenri. - Fix repeated
--arch,--source-packagesand--permissionsflags inflet buildkeeping only the values of the last occurrence (action="extend"on each) (#6578) by @ndonkoHenri. - Fix
flet build apkfailing atmergeDebugNativeLibswithN files found with path 'lib/<abi>/libc++_shared.so'when an app combinesserious_python_androidwith another Flutter plugin that also bundles the NDK C++ runtime (#6570, #6571) by @ndonkoHenri. - Specify
handlersignatures insubscribeandsubscribe_topicmethods ofPubSubClientfor better type checking (#6549) by @Iaw4tch - Fix
FilePicker.pick_files()on web for slow network shares or slow machines: passcancel_upload_on_window_blur=Falseto prevent valid file selections from being reported as cancelled when the browser window loses focus during file picking (#771, #6573) by @ndonkoHenri. - Support
PagePlatform.ANDROID_TVinPage.get_device_info()retrieval (#6604) by @bl1nch. - Fix
ProgressRing.year_2023being ignored, so the control correctly switches between the latest and 2023 Material Design appearances (#6614) by @ndonkoHenri. flet build ipa/iosapps that ship ctypes packages with plain.dylibshared libraries (e.g.llama-cpp-python) now load them on the iOS simulator instead of failing at launch with adlopenplatform mismatch (have 'iOS', need 'iOS-simulator'); the iOS runtime also now bundles the_multiprocessingextension (importable, not spawnable). Bumps the pinned bundle toserious_python4.2.1 / python-build20260701(serious_python#223) by @ndonkoHenri, @FeodorFitsner.- Improve performance of checking added/removed controls in Session.patch_control from O(N²) to O(N) (#6651) by @davidlawson.
- Fix stateful controls inside
ResponsiveRow(video players, WebViews, scroll positions) losing their state whenever a window resize crossed a breakpoint and the layout switched between a single row and wrapping (#6661, #6663) by @FeodorFitsner.
Documentation
- Improve
FilePicker.save_file()documentation: on desktop, passingsrc_byteswrites those bytes to the selected file (#6573) by @ndonkoHenri.
Release notes
Open source →No changes in the
fletDart package; version bumped for release coordination with the multi-version bundled CPython support on the Python side (#6577). - Add support for Python
-
0.85.308 Jun 2026Release notes
Open source →What's Changed
Improvements
- Allow
[tool.flet.android.permission]values to be TOML inline tables in addition to booleans — eachkey = "value"entry adds anandroid:<key>="<value>"attribute to the generated<uses-permission>element, unlocking modifiers likeandroid:maxSdkVersionandandroid:usesPermissionFlagsthat real-world Android permissions (e.g. Bluetooth LE) require. The boolean form and the--android-permissionsCLI flag are unchanged; a non-empty inline table is always emitted, an empty table ({}) is treated asfalse, and invalid value types fail the build with a clear error (#6550, #6551) by @FeodorFitsner. - Add
[tool.flet.android.provider]for declaring custom<provider>entries in the generatedAndroidManifest.xml. Each table key is the provider'sandroid:name; entries becomeandroid:<key>="<value>"attributes on the generated element. A reservedmeta_datasub-table emits nested<meta-data>children (scalar values render asandroid:value="…"; inline-table values render asandroid:<k>="<v>"soandroid:resource="@xml/…"works).false/{}skip the entry;trueand invalid value types fail the build with a clear error. The built-inandroidx.core.content.FileProviderblock is unchanged (#6556, #6559) by @FeodorFitsner. - Upgrade the bundled Pyodide runtime in the
flet build webtemplate from0.27.5to0.27.7(includesmicropip0.9.0) (#6549) by @FeodorFitsner. - Drop generated
web/canvaskit/build artifacts (canvaskit.js/.wasm/.symbolsand thechromium/andskwasm/skwasm_stvariants) from theflet build webtemplate — these are produced by the Flutter web build and should not have been committed into the cookiecutter template (#6549) by @FeodorFitsner. - Cache the downloaded
flet-build-template.zipacross builds. The build template is bound to an exact Flet version and is immutable, so on everyflet build/flet debugafter the first, the CLI now uses a previously-downloaded zip from$FLET_CACHE_DIR/build-template/v<flet-version>/(defaulting to~/.flet/cache/build-template/v<flet-version>/) instead of re-fetching it via cookiecutter. The CLI also exportsFLET_CACHE_DIRinto the child Gradle process, soserious_python_android>= 1.0.1 lands its Python dist tarballs (python-android-dart-<py>-<abi>.tar.gz) in the same cache root by default — fixing the multi-minute "Creating app shell" /downloadDistArchive_*delay on every Android debug build. Custom--templateURLs and the local-dev template path are unchanged (#6555, #6558) by @FeodorFitsner. - Bump the bundled build template's
serious_pythondependency from1.0.0to1.0.1so Android builds pick up the new persistent Python-tarball cache + conditional-GET revalidation introduced inserious_python1.0.1 (#6558) by @FeodorFitsner.
Bug fixes
- Fix
flet.Router's defaulton_view_popnavigating to the wrong URL when anoutlet=Truelayout sits between two views inmanage_views=Truemode. Popping such a view now targets the previous view entry's resolved URL — skipping outlet layouts and componentless grouping routes — instead ofchain[-2], which could equal the current view's URL and strand the page route, making the next navigation to it a no-op (#6533) by @FeodorFitsner. - Fix
flet-audio.Audio.play()/seek()timing out when replaying after playback had completed: under the defaultReleaseMode.RELEASEthe source is freed on completion and is now re-prepared on replay (#6536, #6538) by @ndonkoHenri. - Fix
ft.run(view=ft.AppView.FLET_APP_HIDDEN)briefly flashing the native window in the top-left corner during Windows desktop startup. The Windows runner now respectsFLET_HIDE_WINDOW_ON_STARTand skips the first-frameShow()call so the window stays hidden untilpage.window.visible = True, matching the Linux desktop behavior; the same fix is applied to theflet build windowstemplate runner so generated apps behave consistently. On Linux, pre-show window placement actions (page.window.center(),page.window.alignment) are now deferred until the window first becomes visible to avoid an analogous flash, and the window'sfocusedstate is preserved when aprevent_closehandler cancels a close attempt (#5897, #5914, #6527) by @ihmily.
Full Changelog: v0.85.2...v0.85.3
Release notes
Open source →Improvements
- Allow
[tool.flet.android.permission]values to be TOML inline tables in addition to booleans — eachkey = "value"entry adds anandroid:<key>="<value>"attribute to the generated<uses-permission>element, unlocking modifiers likeandroid:maxSdkVersionandandroid:usesPermissionFlagsthat real-world Android permissions (e.g. Bluetooth LE) require. The boolean form and the--android-permissionsCLI flag are unchanged; a non-empty inline table is always emitted, an empty table ({}) is treated asfalse, and invalid value types fail the build with a clear error (#6550, #6551) by @FeodorFitsner. - Add
[tool.flet.android.provider]for declaring custom<provider>entries in the generatedAndroidManifest.xml. Each table key is the provider'sandroid:name; entries becomeandroid:<key>="<value>"attributes on the generated element. A reservedmeta_datasub-table emits nested<meta-data>children (scalar values render asandroid:value="…"; inline-table values render asandroid:<k>="<v>"soandroid:resource="@xml/…"works).false/{}skip the entry;trueand invalid value types fail the build with a clear error. The built-inandroidx.core.content.FileProviderblock is unchanged (#6556, #6559) by @FeodorFitsner. - Upgrade the bundled Pyodide runtime in the
flet build webtemplate from0.27.5to0.27.7(includesmicropip0.9.0) (#6549) by @FeodorFitsner. - Drop generated
web/canvaskit/build artifacts (canvaskit.js/.wasm/.symbolsand thechromium/andskwasm/skwasm_stvariants) from theflet build webtemplate — these are produced by the Flutter web build and should not have been committed into the cookiecutter template (#6549) by @FeodorFitsner. - Cache the downloaded
flet-build-template.zipacross builds. The build template is bound to an exact Flet version and is immutable, so on everyflet build/flet debugafter the first, the CLI now uses a previously-downloaded zip from$FLET_CACHE_DIR/build-template/v<flet-version>/(defaulting to~/.flet/cache/build-template/v<flet-version>/) instead of re-fetching it via cookiecutter. The CLI also exportsFLET_CACHE_DIRinto the child Gradle process, soserious_python_android>= 1.0.1 lands its Python dist tarballs (python-android-dart-<py>-<abi>.tar.gz) in the same cache root by default — fixing the multi-minute "Creating app shell" /downloadDistArchive_*delay on every Android debug build. Custom--templateURLs and the local-dev template path are unchanged (#6555, #6558) by @FeodorFitsner. - Bump the bundled build template's
serious_pythondependency from1.0.0to1.0.1so Android builds pick up the new persistent Python-tarball cache + conditional-GET revalidation introduced inserious_python1.0.1 (#6558) by @FeodorFitsner.
Bug fixes
- Fix
flet.Router's defaulton_view_popnavigating to the wrong URL when anoutlet=Truelayout sits between two views inmanage_views=Truemode. Popping such a view now targets the previous view entry's resolved URL — skipping outlet layouts and componentless grouping routes — instead ofchain[-2], which could equal the current view's URL and strand the page route, making the next navigation to it a no-op (#6533) by @FeodorFitsner. - Fix
flet-audio.Audio.play()/seek()timing out when replaying after playback had completed: under the defaultReleaseMode.RELEASEthe source is freed on completion and is now re-prepared on replay (#6536, #6538) by @ndonkoHenri. - Fix
ft.run(view=ft.AppView.FLET_APP_HIDDEN)briefly flashing the native window in the top-left corner during Windows desktop startup. The Windows runner now respectsFLET_HIDE_WINDOW_ON_STARTand skips the first-frameShow()call so the window stays hidden untilpage.window.visible = True, matching the Linux desktop behavior; the same fix is applied to theflet build windowstemplate runner so generated apps behave consistently. On Linux, pre-show window placement actions (page.window.center(),page.window.alignment) are now deferred until the window first becomes visible to avoid an analogous flash, and the window'sfocusedstate is preserved when aprevent_closehandler cancels a close attempt (#5897, #5914, #6527) by @ihmily.
Release notes
Open source →Bug fixes
- Defer pre-show window placement on Linux (
centerWindow(),setWindowAlignment()) until the window first becomes visible, sopage.window.center()/page.window.alignmentset beforepage.window.visible = Trueno longer flash the window during startup. Also preserve thefocusedstate when aprevent_closehandler cancels a close attempt (#5897, #5914, #6527) by @ihmily.
- Allow
-
0.85.225 May 2026Release notes
Open source →New features
- Add
Route(modal=True)toflet.Routerfor fullscreen-dialog modal overlays that don't replace the underlying view stack — closing the modal pops it without rebuilding the views underneath. Two flavours by placement: top-level modals are global (the base stack is rebuilt from the Router's last non-modal location), nested-child modals are local (the base stack is the chain above the modal in the route tree, so deep-link works from URL alone) (#6516) by @FeodorFitsner. - Add
Route(recursive=True)toflet.Routerso a route can match itself as its own descendant — oneViewper consumed URL segment, ideal for tree-shaped URLs of unbounded depth (/folder/a/b/cproduces a 4-View stack; back-swipe walks one segment at a time). Non-recursive children are tried before self-recursion at every depth, so a specific sibling (e.g.example/:gp*) wins over the recursive:slugwithout duplicating it at every level (#6516) by @FeodorFitsner.
Improvements
flet.Router's defaulton_view_popnow navigates to the matched chain's parent (chain[-2].resolved_path) instead ofviews[-2].route, which is robust against apps that share aView.routevalue between sibling tab roots to suppress switch transitions. Apps that install their ownpage.on_view_popbeforepage.render_views()still take precedence. Each sub-chain (base + modal) renders with its ownLocationInfo, sois_route_active(...)inside a base view sees the base URL while a global modal is open over it (#6516) by @FeodorFitsner.
Bug fixes
- Fix cross-tab session contamination on Flet web: opening the same app URL in a duplicated browser tab no longer steals the original tab's output connection via
sessionStorage-cloned_flet_session_id.REGISTER_CLIENTnow rejects session reuse when the existing session still has a liveconnection, allocating a fresh session for the second tab while preserving legitimate single-tab reconnect after refresh or network blip (whereconnectionis alreadyNone) (#6512, #6513) by @ihmily.
Release notes
Open source →No changes in the
fletDart package; version bumped for release coordination withflet.Routerenhancements on the Python side (modal/recursive route flags, chain-based default pop). - Add
-
0.85.113 May 2026Release notes
Open source →Bug fixes
- Fix
TooltipTheme.decorationso it applies to controls usingft.Tooltip(...)when the tooltip does not explicitly setdecorationorbgcolor(#6432, #6482) by @ndonkoHenri. - Fix
flet-geolocator.Geolocatorreliability on web and desktop:get_last_known_position()no longer crashes withTypeError: argument after ** must be a mapping, not NoneTypeand now returnsOptional[GeolocatorPosition];get_current_position()no longer hangs forever on web (Dart-side workaround for the upstreamgeolocator_web4.1.3inMicroseconds/inMillisecondstimeout typo) and uses sensible web defaults (time_limit: 30s,maximum_age: 5m); the previously-droppedconfigurationargument now actually reachesgetCurrentPositionon the Dart side; the position stream is gated behind a registeredon_position_change/on_errorhandler (with cancel-on-update to prevent leaks); and platform exceptions (LocationServiceDisabledException,PermissionDeniedException,PermissionDefinitionsNotFoundException,PermissionRequestInProgressException,PositionUpdateException,TimeoutException) are now translated into actionable error messages and surfaced to Python asRuntimeErrorwithout the defaultException:prefix (#6487) by @FeodorFitsner. - Fix PEP 508 markers on
flet'soauthlib/httpxdeps not actually excluding those packages under Pyodide: theflet build webpackage platform has been renamed fromPyodidetoEmscriptento matchplatform.system()inside the Pyodide runtime, and the markers now useplatform_system != 'Emscripten', so the exclusion works both viaflet buildand a directmicropip.install("flet")in a Pyodide REPL. Requiresserious_python>= 1.0.0, which is now pinned in theflet buildtemplate (#6492) by @FeodorFitsner.
Release notes
Open source →No changes in the
fletDart package; version bumped for release coordination withflet-geolocatorfixes on the Python side. - Fix
-
0.85.008 May 2026Release notes
Open source →New features
- Add configurable built-in, custom, hidden, and normal/fullscreen-specific controls to
flet-video;Video.take_screenshot()for capturing video frames; andVideo.on_position_change/Video.on_duration_changeevents (#6463) by @ndonkoHenri. - Add declarative
ft.Routercomponent for@ft.componentapps with nested routes, layout routes with outlets, dynamic segments, optional segments, splats, custom regex constraints, data loaders, active link detection, authentication patterns, andmanage_views=Truemode for view-stack navigation with swipe-back gestures andAppBarback button on mobile (#6406) by @FeodorFitsner. - Add
ft.use_dialog()hook for declarative dialog management from within@ft.componentfunctions, with frozen-diff reactive updates and automatic open/close lifecycle (#6335) by @FeodorFitsner. - Add
scrollable,pin_leading_to_top, andpin_trailing_to_bottomproperties toNavigationRailfor scrollable content with optional pinned leading/trailing controls (#1923, #6356) by @ndonkoHenri. - Add scroll support to
ResponsiveRowfor responsive layouts whose content exceeds the available height (#2590, #6417) by @ndonkoHenri. - Add
issuesproperty toCodeEditor(along withIssueandIssueTypetypes) for displaying code analysis error markers in the gutter, with analysis performed on the Python side (#6407) by @FeodorFitsner. - Add
Page.pop_views_until()to pop multiple views and return a result to the destination view (#6326, #6347) by @brunobrown. - Make
NavigationDrawerDestination.labelaccept custom controls and addNavigationDrawerTheme.icon_theme(#6379, #6395) by @ndonkoHenri. - Add
local_positionandglobal_positiontoDragTargetEventfor target-relative and global pointer coordinates (#6387, #6401) by @ndonkoHenri. - Added PCM16 streaming to
AudioRecorder, includingon_streamchunks and direct upload support viaAudioRecorderUploadSettings(#5858, #6423) by @ndonkoHenri. - Add
Page.theme_animation_stylefor customizing the duration and curve of the theme cross-fade betweenthemeanddark_theme(or disabling it withAnimationStyle.no_animation()), exposing Flutter'sMaterialApp.themeAnimationStyle(#6476) by @FeodorFitsner.
Breaking changes
- Remove deprecated module-level
margin,padding,border, andborder_radiushelper functions (all(),symmetric(),only(),horizontal(),vertical()) in favor of the correspondingMargin,Padding,Border, andBorderRadiusclassmethods (#6425) by @ndonkoHenri.
Deprecations
- Deprecate
DragTargetEvent.x,DragTargetEvent.y, andDragTargetEvent.offset; uselocal_positionfor target-relative coordinates orglobal_positionfor global coordinates instead. These APIs are scheduled for removal in0.88.0(#6387, #6401) by @ndonkoHenri. - Deprecate
Video.show_controls; setVideo.controlstoNoneto hide controls. This API is scheduled for removal in0.88.0(#6463) by @ndonkoHenri. - Deprecate
Video.playlist_add()andVideo.playlist_remove(); mutateVideo.playlistdirectly with list methods such asappend()andpop(). These APIs are scheduled for removal in0.88.0(#6463) by @ndonkoHenri.
Bug fixes
- Fix control diffing for controls nested inside
@valuedataclass objects so they keep the nearest control parent/page context, and restore optional structured properties that are cleared toNoneand later set again (#6463) by @ndonkoHenri. - Fix
PageandViewvertical centering when scrolling is enabled, including hidden scrollbars, so short content remains centered in the viewport (#6446, #6450) by @ndonkoHenri. - Reduce Linux memory retention when repeatedly removing
flet_video.Videocontrols by linkingmedia_kitvideo apps against mimalloc in run and build flows (#6164, #6416) by @ndonkoHenri. - Fix
flet buildandflet publishdependency parsing forproject.dependenciesand Poetry constraints with</<=, and add coverage for normalized requirement handling (#6332, #6340) by @td3447. - Fix
CodeEditorbackground not filling the entire area whenexpand=True(#6407) by @FeodorFitsner. - Handle unbounded width in
ResponsiveRowwith an explicit error, treat child controls withcol=0as hidden, and clarifyContainerexpansion behavior whenalignmentis set (#1951, #3805, #5209, #6354) by @ndonkoHenri. - Fix
find_platform_imageselecting incompatible icon formats (e.g..icnson Windows) by ranking glob results per target platform (#6381) by @HG-ha. - Fix
page.window.destroy()taking several seconds to close Windows desktop apps whenprevent_closeis enabled (#5459, #6428) by @ndonkoHenri. - Fix
Page.show_drawer(),close_drawer(), and root/top view accessors (appbar,drawer,navigation_bar,controls, ...) failing withTypeErrorunderPage.render_views()by unwrapping component-wrapped views and normalizing single-view returns (#6413, #6414) by @FeodorFitsner. - Fix
auto_scrollon scrollable controls silently doing nothing unlessscrollwas also explicitly set (#6397, #6404) by @ndonkoHenri. - Fix Flet web returning
index.htmlwith a200 OKfor missing asset files; requests for paths with a file extension other than.htmlnow return a proper404, while route-like paths still fall back toindex.htmlfor SPA routing (#6425) by @ndonkoHenri. - Fix
Lottiefailing to load local asset files on Windows desktop (and unreliably on other desktop platforms), so animations referenced bysrc="file.json"from the app'sassets/directory now display correctly (#6386, #6426) by @ndonkoHenri. - Fix
Page.on_resizeandPage.on_media_changenot firing after mobile orientation changes (#6457, #6423) by @ndonkoHenri. - Fix
flet packdesktop packaging so Windows and Linux bundles include the expected client archive, and Windows taskbar pins point to the packed app instead of the cachedflet.exe(#5151, #6403) by @ndonkoHenri. - Fix environment variable priority in
flet buildtemplate: inherit fromPlatform.environmentand useputIfAbsentfor FLET_* variables so pre-set system env vars are not overwritten (#6394) by @Bahtya. - Fix
NavigationBarDestination.selected_iconrendering wrongly when provided as anIconcontrol (#6460, #6468) by @ndonkoHenri. - Fix 3- and 4-digit hex color shorthand (e.g.
#c00,#fc00) rendering as invisible by expanding them to their full 6/8-digit forms (#6419, #6421) by @ndonkoHenri. - Fix
LineChartEvent.spotsreturning undecoded MessagePack extension values instead ofLineChartEventSpotobjects (#6443, #6468) by @ndonkoHenri. - Fix
LineChart(and other charts) silently dropping customChartAxisLabelentries whosevaluematched a tick only after floating-point rounding (e.g.0.1,0.2,0.3) by switching label lookup to a tolerance-based comparison scaled to the axis interval (#6445, #6459) by @KangZhaoKui. - Fix absolute-path
src(e.g.Image(src="/images/foo.svg")) breaking on web when the app is mounted at a non-root URL, passdata:/blob:URIs through the asset resolver unchanged, preserve origin-relative semantics whenassets_diris unset, and add awindow.flet.assetsDirJS-interop bridge so embedding hosts can supplyassets_dirto the top-levelFletApp(#6470) by @FeodorFitsner. - Fix unbounded browser memory growth in
MatplotlibCharton Flutter web (CanvasKit/WASM) during animations by replacing theCanvas+capture()rendering path with a dedicatedMatplotlibChartCanvaswidget that composites matplotlib diff frames in CPU memory; also fixes Safari async PNG decode (EncodingError: Loading error.), a render/figure.savefig()race that crashed the toolbar Download, and pan/zoom playback lag from buffered pointer events (#6473) by @FeodorFitsner. - Fix
Durationfields (and otherint-typed properties) silently decoding to0when given a Pythonfloat(e.g.Duration(seconds=2.0)causingPage.theme_animation_styleto end instantly) by coercingdoubletointin the Dart-sideparseInt(#6478, #6480) by @FeodorFitsner.
Documentation
- Improve CrocoDocs API reference rendering with formatted signatures, modern type annotations, and cleaner cross-reference labels for extension packages (#6442) by @ndonkoHenri.
- Add
crocodocs watchcommand for hot-reload docs development with file-watching, debounced regeneration, and optional child process management (#6402) by @ndonkoHenri.
Other changes
- Add a declarative
ReorderableListViewapp example showing add, remove, and reorder flows with stable item identity (#6374) by @FeodorFitsner. - Centralize Linux apt dependencies in
flet.utils.linux_depsand update CI workflows and publish docs to consume them dynamically (#6357, #6383) by @ndonkoHenri. - Bump
serious_pythonto0.9.12in theflet buildtemplate (#6461) by @FeodorFitsner.
Release notes
Open source →New features
- Add
parseControlWidget()andparseControlWidgets()utilities for converting Flet controls in protocol values to Flutter widgets (#6463) by @ndonkoHenri.
Bug fixes
- Preserve viewport minimum constraints for short scrollable
View,Column, andRowcontent so main-axis alignment still applies (#6446, #6450) by @ndonkoHenri. - Handle unbounded width in
ResponsiveRowwith an explicit error and treat child controls withcol=0as hidden at the current breakpoint (#1951, #3805, #6354) by @ndonkoHenri. - Fix
page.window.destroy()taking several seconds to close Windows desktop apps whenprevent_closeis enabled (#5459, #6428) by @ndonkoHenri. - Fix
flet packdesktop packaging so Windows and Linux bundles include the expected client archive, and Windows taskbar pins point to the packed app instead of the cachedflet.exe(#5151, #6403) by @ndonkoHenri. - Resolve absolute-path
src(e.g.Image(src="/images/foo.svg")) againstassets_diron web so embedded apps mounted at non-root URLs load assets correctly, passdata:/blob:URIs through unchanged, preserve origin-relative semantics whenassets_diris unset, and add awindow.flet.assetsDirJS-interop bridge so embedding hosts can supplyassets_dirto the top-levelFletApp(#6470) by @FeodorFitsner. - Coerce
doubletointinparseIntso float values passed intoint-typed protocol fields (e.g.Duration(seconds: 2.0)) decode correctly instead of falling back to the default (#6478, #6480) by @FeodorFitsner.
- Add configurable built-in, custom, hidden, and normal/fullscreen-specific controls to
-
0.84.001 Apr 2026Release notes
Open source →Improvements
- Migrate Flet docs from MkDocs to Docusaurus for a more maintainable documentation pipeline (#6359) by @FeodorFitsner.
- Migrate examples into standalone projects with metadata, dependencies, and assets to improve discovery and make every sample runnable as-is (#6281, #6355) by @InesaFitsner.
Bug fixes
-
0.83.129 Mar 2026Release notes
Open source →Bug fixes
- Fix solitaire tutorial and drag examples to use
local_delta.xandlocal_delta.yinstead of removeddelta_xanddelta_y(#6317, #6344) by @Krishnachaitanyakc. - Fix inherited dataclass field validation rules applying to overridden subclass fields and breaking
flet-datatable2on0.83.0(#6349, #6350) by @ndonkoHenri.
- Fix solitaire tutorial and drag examples to use
-
0.83.026 Mar 2026Release notes
Open source →New features
- Add customizable scrollbars for scrollable controls and pages (#5912, #6282) by @ndonkoHenri.
- Add scrolling support and richer change events to
ExpansionPanelList(#6294) by @ndonkoHenri. - Expand
SharedPreferencesto supportint,float,bool, andlist[str]values (#6304, #6267) by @ndonkoHenri.
Improvements
- Speed up control diffing and nested value tracking with sparse
Propupdates and@valuetypes (#6098, #6270, #6117, #6296) by @FeodorFitsner. - Consolidate app/build templates into the monorepo and publish pre-release
fletpackages and template artifacts from CI (#6306, #6331) by @FeodorFitsner. - Move desktop client binaries from PyPI wheels to GitHub Releases and unify desktop packaging around
flet-desktop(#6290, #6309) by @FeodorFitsner. - Lightweight dataclass validation and deprecation with
Annotated+ auto-added deprecation admonitions in docs (#6278) by @ndonkoHenri.
Bug fixes
- Align Dart-side default values with Python across core and extension packages (#6329, #6330) by @FeodorFitsner.
- Skip redundant page auto-updates after handlers call
.update()explicitly (#6236, #6298) by @FeodorFitsner. - Fix
ReorderableListViewreorder event deserialization for start/end callbacks (#6177, #6315) by @ndonkoHenri. - Skip loading
micropipfor Pyodide apps that already define dependencies inpyproject.toml(#6259, #6300) by @FeodorFitsner.
Release notes
Open source →New features
- Add customizable scrollbars for scrollable controls and pages (#5912, #6282) by @ndonkoHenri.
- Add scrolling support and richer change events to
ExpansionPanelList(#6294) by @ndonkoHenri. - Expand
SharedPreferencesto supportint,float,bool, andlist[str]values (#6304, #6267) by @ndonkoHenri.
Improvements
- Speed up control diffing and nested value tracking with sparse
Propupdates and@valuetypes (#6098, #6270, #6117, #6296) by @FeodorFitsner. - Consolidate app/build templates into the monorepo and publish pre-release
fletpackages and template artifacts from CI (#6306, #6331) by @FeodorFitsner. - Move desktop client binaries from PyPI wheels to GitHub Releases and unify desktop packaging around
flet-desktop(#6290, #6309) by @FeodorFitsner.
Bug fixes
- Align Dart-side default values with Python across core and extension packages (#6329, #6330) by @FeodorFitsner.
- Skip redundant page auto-updates after handlers call
.update()explicitly (#6236, #6298) by @FeodorFitsner. - Fix
ReorderableListViewreorder event deserialization for start/end callbacks (#6177, #6315) by @ndonkoHenri. - Skip loading
micropipfor Pyodide apps that already define dependencies inpyproject.toml(#6259, #6300) by @FeodorFitsner.
-
0.82.210 Mar 2026Release notes
Open source →Bug fixes
- Lazy-load optional auth dependencies to avoid import-time failures in web/Pyodide startup (#6258, #6280) by @ndonkoHenri.
- Pin
binaryornotbelow0.5to fix build-template UTF-8 decode errors (#6276, #6279) by @ndonkoHenri.
-
0.82.109 Mar 2026Nothing published for this version
-
0.82.004 Mar 2026Release notes
Open source →New features
- Add Auth0
audiencesupport through OAuthauthorization_params(#3775, #6205). - Add
Map.get_camera(),MapEventType, and richerMapEventpayloads inflet-map(#6196, #6208).
Improvements
- Refactor ads controls:
InterstitialAdis now aService, andBannerAdis now aLayoutControl(#6194, #6235). - Improve
CodeEditorwith Chinese pinyin input support and aligned gutter rendering (#6211, #6243, #6244). - Add the
Trolliapp declarative example rewrite (#6242).
Bug fixes
- Fix disabled-state handling across
Tabs,TabBar,Tab, andTabBarView(#6220, #6224). - Fix a
WebViewnull-check crash (Null check operator used on a null value) (#6238).
Other changes
- Add Auth0
-
0.81.024 Feb 2026Release notes
Open source →New features
- Add
Cameracontrol (#6190). - Add
CodeEditorcontrol (#6162). - Add
PageViewcontrol (#6158). - Add color picker controls based on
flutter_colorpicker(#6109). - Add Matrix4-based
LayoutControl.transformandRotatedBoxcontrol (#6198). - Add
LayoutControl.on_size_changeevent for size-aware layouts (#6099). - Add
Heroanimations (#6157). - Add clipboard image/file set and get APIs (#6141).
- Add web
FilePickerwith_datasupport for file content (#6199). - Add platform locale info and locale change events (#6191).
- Add
ignore_up_down_keystoTextFieldandCupertinoTextField(#6183). - Add
flet build --artifactand iOS simulator build targets (#6074, #6188).
Improvements
- Optimize
object_patchmemory churn (#6204). - Skip component migrate/diff when function signatures differ (#6181).
Bug fixes
- Fix memory leaks in Flet web app (#6186).
- Fix desktop window frameless/titlebar update sync and progress bar clearing (#6114).
- Fix first-time button
stylepatching and clear stale style state (#6119). - Fix map layer rebuilds on marker updates (#6113).
- Fix
AlertDialogandCupertinoAlertDialogbarrier color updates (#6097). - Fix
ControlEventruntime type hints (#6102).
Other changes
- Bump Flutter to 3.41.2.
- Register MIME types for
.mjsand.wasm(#6140).
Release notes
Open source →New features
- Add
Cameracontrol (#6190). - Add
CodeEditorcontrol (#6162). - Add
PageViewcontrol (#6158). - Add color picker controls based on
flutter_colorpicker(#6109). - Add Matrix4-based
LayoutControl.transformandRotatedBoxcontrol (#6198). - Add
LayoutControl.on_size_changeevent for size-aware layouts (#6099). - Add
Heroanimations (#6157). - Add clipboard image/file set and get APIs (#6141).
- Add web
FilePickerwith_datasupport for file content (#6199). - Add platform locale info and locale change events (#6191).
- Add
ignore_up_down_keystoTextFieldandCupertinoTextField(#6183).
Improvements
- Optimize
object_patchmemory churn (#6204). - Skip component migrate/diff when function signatures differ (#6181).
Bug fixes
- Fix memory leaks in Flet web app (#6186).
- Fix desktop window frameless/titlebar update sync and progress bar clearing (#6114).
- Fix first-time button
stylepatching and clear stale style state (#6119). - Fix map layer rebuilds on marker updates (#6113).
- Fix
AlertDialogandCupertinoAlertDialogbarrier color updates (#6097). - Fix
ControlEventruntime type hints (#6102).
Other changes
- Bump Flutter to 3.41.2.
- Register MIME types for
.mjsand.wasm(#6140).
- Add
-
0.80.529 Jan 2026 -
0.80.423 Jan 2026 -
0.80.322 Jan 2026Release notes
Open source →- Lazy loading of icons, theme for faster app startup (#6043).
- feat: add
localeprop toCupertinoDatePicker,DatePicker,DateRangePicker,TimePicker(#6030). - Allow installing Flet packages in runtime with uv (#6037).
- Python wheels for Ubuntu 20.04-24.04 (#6035).
- Disable Rive in desktop client light (#6032).
- Fix desktop light package versioning (#6031).
- Rive 0.14.0 (#6025).
- fix: Convert
datetimeinstances to UTC while passing over the wire (#6023). - feat(flet-charts): Allow
badge_positionandtitle_positionofPieChartSectionaccept values >=1.0(#6024). - Add position details to
GestureDetector.on_tapevent (#6016). - Fix Android platform check to exclude web (#6013).
Release notes
Open source →- feat: add
localeprop toCupertinoDatePicker,DatePicker,DateRangePicker,TimePicker(#6030). - Rive 0.14.0 (#6025).
- feat(flet-charts): Allow
badge_positionandtitle_positionofPieChartSectionaccept values >=1.0(#6024). - Add position details to
GestureDetector.on_tapevent (#6016). - Fix Android platform check to exclude web (#6013).
- feat:
parseEnumutility function.
-
0.80.214 Jan 2026Release notes
Open source →- OAuth fixes and updated examples (#5996).
- Examples cleanup (#5997).
- Fix wrong
LinearGradientalignment defaults + allow multiple use of--excludeoption inflet build(#5986). - Update TypeVar definition for covariant typing in Ref class (#5994).
- feat: add
on_long_pressandon_hoverevents toIconButton(#5984). - replace all
asyncio.iscoroutinefunctionwithinspect.iscoroutinefunction(#5928). - Fix: Control with ID xxx is not registered for
flet_permission_handlerwhen using Python 3.14 (#5896).
-
0.80.102 Jan 2026Release notes
Open source →- Fix
flet publishto sub-directories, Icons Browser and other Gallery examples updated #5964.
- Fix
-
0.80.025 Dec 2025 -
0.28.320 May 2025Release notes
Open source →- New: Multiple subscribers can subscribe to a published topic by
send_all_on_topic(#5303) - Fixed: Local Images Not Rendering in Android App using Flet 0.27.6 (#5198)
- Fixed: FilePicker.save_file() opens blank gray screen in APK build (works fine in VS) (#5301)
- Fixed: Routing / Navigation broken since flet 0.28.2 (#5302)
- New: Multiple subscribers can subscribe to a published topic by
-
0.28.210 May 2025 -
0.28.108 May 2025Nothing published for this version
-
0.28.008 May 2025Release notes
Open source →- feat(cli):
flet -Vas alternative toflet --version(#4791) - New Features and Flutter 3.29 (#4891)
- Fixed:
Dropdown.expandhas no effect (#5042) - feat: expose events (
on_double_tap,on_pan_start) inWindowDragArea(#5043) - feat: custom
ReorderableListViewdrag handle listeners (#5051) - Fixed:
LineChartDataPoint.tooltipnot properly rendered (#5105) - Fixed: broken code in
Page.__on_authorize_async(#5154) - Remove Flet v0.25 deprecations (#5155)
- Prevent platform back button from popping a route with pop confirmation event (#5280)
- Fixed: SearchBar does not handle capitalization correctly (#5014)
- Fixed:
FilePickerupload fails if original filename is modified (#5037)
- feat(cli):
-
0.27.611 Mar 2025Release notes
Open source →- Fix
flet build: allow dependencies with commas (#5033) - Show app startup screen by default (#5036)
- fix:
Textfieldcursor position changes when modifying field content inon_change(#5019) - Remove deprecated
Control.update_async()method (#5005) - fix: incorrect positioning of non-FAB controls assigned to page.floating_action_button (#5049)
- Fix
-
0.27.505 Mar 2025Release notes
Open source →- Added
FletApp.showAppStartupScreenandFletApp.appStartupScreenMessageproperties. - Added
tool.flet.splash.icon_bgcolorandtool.flet.splash.icon_dark_bgcolorsettings for Android splash screen icon image. - Added
tool.flet.app.boot_screenandtool.flet.app.startup_screensettings for customizing Flet app "loading" screens. - feat:
Dropdown.menu_widthproperty (#5007) - PBKDF2 iteration count increased to 600,000 (#5023)
- Added
-
0.27.401 Mar 2025Release notes
Open source →- Fix: do not remove
flutter-packageson re-build ifdev_packagesconfigured.
- Fix: do not remove
-
0.27.328 Feb 2025 -
0.27.226 Feb 2025Release notes
Open source →- Error on second flet build run "Because {app} depends on flet_{package} from path which doesn't exist" (#4955)
- Editable packages in pyproject.toml to install from a path by flet build command (#4963)
- Setting Android manifest
<application>element properties inpyproject.toml(#4977) - Fixed regression: Added back
Control.build()method.
-
0.27.122 Feb 2025 -
0.27.022 Feb 2025Release notes
Open source →DropdownMenucontrol (#1088)- feat:
ReorderableListViewControl (#4865) - Remove v0.24.0 deprecations #4932)
- Implement
Container.dark_themeproperty (#4857) - Upgrade to Pyodide 0.27 for
httpxSupport (#4840) - Remove
CupertinoCheckbox.inactive_colorin favor offill_color(#4837) flet build: use Provisioning Profile to sign iOS app archive (.ipa), deprecate--teamoption (#4869)- feat:
flet doctorCLI command (#4803) - feat: implement button themes (for
ElevatedButton,OutlinedButton,TextButton,FilledButton,IconButton) (#4872) ControlEvent.datashould be of typeOptional[str]and default toNone(#4786)flet build: add--source-packagesto allow installing certain Python packages from source distros (#4762)- disable markup for flet-cli stdout logs (#4796)
- Fixed: Disable rich's Markup for stdout logs (#4795)
- Fixed: Setting
SearchBar.bar_border_sideisn't visually honoured (#4767) - Fixed: Dropdown: Long options cause the down-arrow to overflow (#4838)
- Fixed: CupertinoSlider initialisation does not allow values less then zero/greater then 1 (#4853)
- Fixed: Same code shows different appearance in Flet APP/Web/PC local. (#4855)
- Fixed: Transforming scale renders a grey screen (#4759)
- Fixed: UnicodeDecodeError when using accented characters in manifest.json (#4713)
- Fixed: Implement
SearchBar.blur()to programmatically unfocus the bar (#4827)
-
0.26.026 Jan 2025Release notes
Open source →- Flutter extensions:
flet_*packages moved to separate repositories (#4721) - Automatic installation of Flutter, JDK and Android SDK (#4721)
- Migrated to Flutter 3.27.0 (#4593)
- New control properties, Flutter 3.27 fixes (#4703)
- Optional on-demand creation of
ListView.controls(#3931) - Reset
InteractiveViewertransformations (#4391) - Passthrough of mouse events from main window to other applications (#1438)
- Remove v0.26.0-related deprecations (#4456)
- Implemented
Window.ignore_mouse_events(#4465) - Adding Google/Android TV platform support (#4581)
- Remove
Optional[]from predefined typing*Values (#4702) - Throttle
InteractiveViewerupdate events (#4704) - Fixed: Update project_dependencies.py (#4459)
- Fixed:
SafeAreaobject has no attribute_SafeArea__minimum(#4500) - Fixed: Tooltip corruption in
SegmentandBarChartRodonupdate()(#4525) - Fixed: Setting
CheckBox.border_side.stroke_alignto an Enum fails (#4526) - Fixed:
ControlStateshould be resolved based on user-defined order (#4556) - Fixed: broken
Dismissible.dismiss_direction(#4557) - Fixed: Fix Rive not updating (#4582)
- Fixed:
DatePickerregression with first and last dates (#4661) flet buildcommand: Copyflutter-packages, support for platform-specific dependencies (#4667)- Fixed:
CupertinoBottomSheetapplies a red color and yellow underline toTextcontent (#4673) - Fixed: setting
ButtonThemedisplays a grey screen (#4731) - Fixed:
Textfieldinput border color considers user-specifiedborder_colorproperty (#4735) - Fixed: make
Tooltip.messagea required parameter (#4736)
- Flutter extensions:
-
0.25.213 Dec 2024Release notes
Open source →Bug fixes
- Fix
flet publishcreates broken website if norequirements.txtorpyproject.tomlfound (#4493). - Fix PyInstaller hook to avoid download Flet app bundle on first run (#4549).
- Support
git,path,urlPoetry-style dependencies inpyproject.toml(#4554). - Fixed broken
Map.center_on()and default animations (#4519). - Fixed Tooltip corruption in
SegmentandBarChartRodonupdate()(#4525). - Fixed Setting
CheckBox.border_side.stroke_alignto an Enum fails (#4526). - Fixed
ControlState shouldbe resolved based on user-defined order (#4556). - Fixed broken
Dismissible.dismiss_direction(#4557).
- Fix
-
0.25.129 Nov 2024Release notes
Open source → -
0.25.028 Nov 2024Release notes
Open source →New controls
- Mobile Ads (
BannerandInterstitial) (details and example). Buttoncontrol (#4265) - which is just an alias forElevatedButtoncontrol.
Breaking changes
- Refactor
BadgeControl to a Dataclass; added newbadgeproperty to all controls (#4077).
Other changes
- Added
{value_length},{max_length}, and{symbols_left}placeholders toTextField.counter_text(#4403). - Added
--skip-flutter-doctorto build cli command (#4388). WebViewenhancements (#4018).Mapcontrol enhancements (#3994).- Exposed more
Themeprops (#4278, #4278). - Exposed more properties in multiple Controls (#4105)
- Added
__contains__methods in container-alike Controls (#4374). - Added a custom
Markdowncode theme (#4343). - Added
barrier_colorprop to dialogs (#4236). - Merged
iconandicon_contentprops intoicon: str | Control(#4305). - Migrated
colorsandiconsvariables to Enums (#4180). - TextField:
suffix_icon,prefix_iconandiconcan beControlorstr(#4173). - Added
--pyinstaller-build-argstoflet packCLI command (#4187). - Made SearchBar's view height adjustable; added new properties (#4039).
- Bumped Rive version and fixed Linux app build template for
rive_common.
Bug fixes
- Fixed
Iconrotation (#4384). - Fixed regression in
Markdown.code_themewhen usingMarkdownCodeThemeenum (#4373). - Fixed
SegmentandNavigationBarDestinationaccept only string tooltips (#4326). - Display informative message when
datehas wrong format (#4019). - Fixed
MapConfiguration.interaction_configurationis not honoured (#3976). - Fixed
Video.jump_to()fails with negative indexes (#4294). - Fixed condition in
AppBar.tooltip_opacity(#4280). - Fixed wrong type (asyncio.Future -> concurrent.futures.Future) and handle
CancelledError(#4268). - Fixed clicking on
CupertinoContextMenuActiondoesn't close context menu (#3948). - Fixed dropdown
max_menu_height(#3974). - Fixed prevent button style from being modified in
before_update()(#4181). - Fixed disabling filled buttons is not visually respected (#4090).
- when
labelis set, useMainAxisSize.minfor theRow(#3998). - Fixed
NavigationBarDestination.disabledhas no visual effect (#4073). - Fixed autofill in
CupertinoTextField(#4103). - Linechart:
jsonDecodetooltip before displaying (#4069). - Fixed button's
bgcolor,colorandelevation(#4126). - Fixed scrolling issues on Windows (#4145).
- Skip running flutter doctor on windows if
no_rich_outputisTrue(#4108). - Fixed
TextFieldfreezes on Linux Mint #4422](https://github.com/flet-dev/flet/pull/4422)).
- Mobile Ads (
-
0.24.103 Sep 2024 -
0.24.030 Aug 2024Release notes
Open source →- NEW:
PlaceholderControl (#3646) - NEW:
InteractiveViewerControl (#3645) - NEW: Adding Background/Foreground Services to GeoLocator UPDATE (#3803)
- NEW:
Container.ignore_interactionsproperty (#3639) - NEW: Add
rtlprop to more controls (#3641) - NEW:
TextField.counterproperty (#3676) - NEW: window.icon: make the usage of relative paths possible (#3825)
- NEW: Add event to
flet_videoto know what song is playing (#3772) - NEW: adds
floating_action_button_themeproperty toTheme(#3771) - NEW: Added
on_completedevent toflet_video(#3758) - NEW: Add
focus,on_focus,on_blurtoSearchBar(#3417, #3752) - NEW:
--no-rich-outputflag to prevent rich output (#3708) - CHANGED: make
Tooltipa dataclass which can be used inControl.tooltip(#3837) - CHANGED: wrap
Views into a background container (#3820) - FIXED: export BottomSheetTheme (#3858)
- FIXED: setting SearchBar.value to an empty string is not respected (#3872)
- FIXED: add full-screen events to WindowEventType (#3857)
- FIXED: snackbar margin (#3856)
- FIXED: not error on inputfield when errorText is empty (#3855)
- FIXED:
flet.mapis not available after building app (#3845) - FIXED:
InputFilterclearsTextFieldwhen an invalid character is entered (#3779) - FIXED:
Dropdown.alignmentnot respected (#3737) - FIXED: scrolling issues in
CupertinoPicker(#3678) - FIXED: scrolling controls are not able to scroll due to wrong super class call (#3702)
- FIXED: Dismissible (#3690)
- FIXED:
PieChartEvent.typeon web (#3611) - FIXED:
Switch.widthandheightproperties (#3670) - FIXED: parsing issues in
TextStyleand*Eventclasses (#3551) - FIXED: issues with
*Buttons (#3582) - Handle Multiple Trailing Controls in
CupertinoAppBar(#3603) - Event: implement str and repr magic methods (#3601)
- CHORE: remove handler-subscription and enhance event typing (#3808)
- CHORE: improve type hint for OptionalEventCallable (#3659)
- CHORE: Using
Sequenceinstead oflist(#3661) - CHORE: Bump Flutter packages (#3719)
- CHORE: Cleanup (#3640)
- NEW:
-
0.23.225 Jun 2024Release notes
Open source →- CHANGED: Enhance Typing of Event Handlers (#3523)
- CHANGED: Delete Page.window.on_resize | deprecate Page.on_resize in favor of Page.on_resized (#3516)
- CHANGED: View is not opened on tap (#3513)
- FIXED:
Slider.valuedefaults tomin(#3503) - FIXED: add "hide" and "show" to WindowEventType enum (#3505)
- FIXED: TypeError raised for isinstance check with Union in before_update method (#3499)
- FIXED: Corrected
isinstancecheck inSnackBar.before_updateto use a tuple of types instead of Union, resolving TypeError: "Subscripted generics cannot be used with class and instance checks". - FIXED:
Page.open()breaking after multiple calls. - FIXED: Typo in on_resized setter decorator
-
0.23.120 Jun 2024Release notes
Open source →- FIX: Fix parseFloatingActionButtonLocation() to work on desktop (#3496)
- FIX: Flet 0.23 crashes on Ubuntu 22.04 (#3495)
- FIX: View.floating_action_button_location: conditionally use _set_attr.
- FIX: Import
ParamSpecfromtypingfor Python >3.10. - FIX: replace
len(list(filter(...)))byany(...). - FIX: Make window and browser_context_menu private, and expose respective getters.
-
0.23.018 Jun 2024Release notes
Open source →- NEW:
PermissionHandlercontrol (#3276) - NEW:
Mapcontrol (#3093) - NEW:
Geolocator control(#3179) - NEW:
AutoFillGroupControl (#3047) - NEW: Migrated to Flutter 3.22 (#3396)
- NEW: An ability to access PubSubHub from outside Flet app (#3446)
- NEW:
TextStyleprops:overflow,word_spacing,baseline(#3435) - NEW: Enable/disable browser context menu (#3434)
- NEW:
Container.color_filterproperty (#3392) - NEW:
dropdown.Option.text_styleproperty (#3293) - NEW:
dropdown.Option.contentproperty (#3456) - NEW:
Video.configurationproperty (#3074) - NEW: Enable Impeller on Android and macOS (#3458)
- NEW: AutoComplete: add selected_index read-only property (#3298)
- NEW: Renamed
NavigationDestinationtoNavigationBarDestination(#3172) - CHANGED: Prettify "build" command cli output (#3407)
- CHANGED: Set colorScheme.primary as defaultSideColor (#3421)
- CHANGED: feat(map): add missing py-events, better typing (#3464)
- CHORE: Refactor
numbers.dartutils (#3263) - CHORE: Global Code Refactoring/Clean-up (#3186)
- CHORE: Cleanup (#3406)
- CHORE: Error handling enhancements (#3175)
- CHORE: Improve type hint for run_task and run_thread (#3459)
- CHORE: Move
page.window_*andpage.browser_context_menu_*properties toWindowandBrowserContextMenuclasses (#3463) - FIX:
Container.on_tap_downnot called whenon_clickis not provided (#3442) - FIX: SnackBar bug #3311 (#3313)
- NEW:
-
0.22.209 May 2024 withdrawnNothing published for this version
-
0.22.109 May 2024Release notes
Open source →AutoCompletecontrol (#3003)- Added
--excludeoption toflet buildcommand (#3125) CupertinoTimePicker.alignmentproperty (#3036)- Bump
file_pickerdependency to 8.0.3. - Fix latest flet-build-template version in development mode (#3021)
- Fix
flet --versioncommand for source checkout. - LineChart: fix regression (#3033)
- Fixed: OAuth expiry of token will hang fastapi server (#3150)
- Fixed: Disabled the dropwown, but the color isnot gray (#2989)
- Fixed:
pubspec.yamlfor adding custom Flutter packages requiresdependency_overrides(#3187) - Fixed
disableddropdown (#3183) - Fixed default value for scrollbar thickness (#3147)
- Fixed: autoreload, restrict eventhandler from restart on open (#3098)
- Fixed (#3035) switch Flutter RichText to Text.rich (#3066)
- Fixed: Markdown code block is not selectable (#1753)
-
0.22.010 Apr 2024Release notes
Open source →- Controls enhancement (see #2882 for details).
ThemeEnhancement (#2955).RiveControl (#2841).Control.parentproperty (#2906).Container.on_tap_downevent.- Add
upload_endpoint_pathintoflet.fastapi.app(#2954). - Add checkbox border side state (#2973).
- Global context for session (#2934).
- Fix silent error in
page.run_task(#2959). - Web: patch html title with app_name (#2909).
Container: fix triggered bothon_clickandon_long_pressevents (#2914).
-
0.21.218 Mar 2024Release notes
Open source →- Add
--android-adaptive-icon-backgroundtoflet buildcommand. - Fix for mobile Safari: Store session ID in SessionStorage instead of window.name.
- Fix
_FletSocketServer__receive_loop_taskerror on Linux. - Replace deprecated (in Python 3.12)
datetime.utcnow()withdatetime.now(timezone.utc). - Fix a call to
self.__executor.shutdownfor Python 3.8. - Add client IP and user agent to a session ID.
- Generate crypto-strong strings across the framework.
- Add
-
0.21.107 Mar 2024Release notes
Open source →- Python dependencies bumped and loosen.
- Fixed: "No supported WebSocket library detected." when running web app with Flet 0.21.0 (#2818).
- Fix
EventHandler: do not call it when converter returnedNone.
-
0.21.006 Mar 2024Release notes
Open source →- FastAPI instead of built-in Fletd server. Mixed async/sync apps. (#2700).
CupertinoActivityIndicatorControl (#2762).LottieControl andVideov2 (#2673).CupertinoActionSheetandCupertinoActionSheetActioncontrols (#2763).CupertinoSlidingSegmentedButtonandCupertinoSegmentedButtoncontrols (#2767).CupertinoTimerPickerandCupertinorPickerControls (#2743).CupertinoContextMenuandCupertinoContextMenuActioncontrols (#2772).CupertinoDatePickerControl (#2795).Page.on_app_lifecycle_state_changeevent (#2800).- More
Semanticsproperties andSemanticsServicecontrol (#2731). - Fix container.dart for issue #2628 (#2701).(#2701)
- Adaptive fixes (#2720).
label_styleproperty forCheckbox,Switch, andRadio(#2730).- Additional properties (#2736).
- Reorder
__init__(#2724).
-
0.20.218 Feb 2024Release notes
Open source →- Move
system_overlay_stylefromAppBartoTheme(#2667). flet buildcommand checks minimal Flutter SDK version.- Buttons turn to
CupertinoDialogActioncontrols inside adaptive dialogs. FletAppcontrol takes control create factories from a parent app.
- Move
-
0.20.117 Feb 2024 -
0.20.014 Feb 2024Release notes
Open source →AppBar.system_overlay_styleproperty (#2615).- New
CupertinoButtonprops:filled,style.bgcolor,style.padding,text,icon,icon_color. - Added
NavigationBar.borderproperty which is used in adaptive mode only. Page.designandPagelet.designproperties to force Material, Cupertino or Adaptive design language on entire app (#2607).Page.mediaproperty with the data about obstructed spaces on the device (#2613).- Adaptive buttons (#2591).
Control.on_update()method for better custom controls.--include-packagesoption and support forpubspec.yamlfor custom Flutter packages plus API for adding custom Flutter packages.- Add
rtlproperty to multiple controls (#2582). - Fix: Material icon is shown instead of Cupertino icon if its name is thesame (#2581).
TextStyle.letter_spacingproperty (#2574).Audio,AudioRecorder,VideoandWebViewcontrols moved into separate Flutter packages (#2579).- Introduced
Control.on_update()overridable method (#2578). - New
AlertDialogproperties:icon,bgcolor,elevation. expand_looseproperty for Control and all controls that haveexpandproperty (#2561).- Pyodide v0.25.0.
flet createcommand to show verbose output (#2544).AudioRecordercontrol (#2494).- Bugfix:
flet pack --distpathdeletesdistdirectory (#2500). - Added recursive
adaptiveproperty to all container-alike controls. TextField.text_vertical_alignproperty (#2496).CupertinoButtonControl (#2495).CupertinoListTilecontrol (#2487).- Support for custom Flutter controls (#2482).
Pageletcontrol (#2469).- Add
AppBar.adaptive(#2458). - Cupertino Icons and Colors (#2433).
CupertinoTextfieldcontrol (#2417).FloatingActionButtonLocationoffset (#2411).
-
0.19.015 Jan 2024Release notes
Open source →flet buildto apply Python SSL fix when packaging for iOS and Android (#2349).- Upgrade Android Gradle in flet
build apptemplate (#2350). flet build -vvshould run pip install with verbose output (#2351).- Add Python output/logging to troubleshoot empty screens on startup of built app (#2352).
flet buildshould raise an error when trying to package an app with native modules for iOS or Android (#2356).flet buildto add timestamp (hash) asset with Flet Python app to re-extract when code changes (#2289).- Handle/bypass
if __name__ == "__main__"check on Android. - Support reading dependencies from
pyproject.toml. flet buildto fix--base-urlwith surrounding slashes (#2369).CupertinoAlertDialog,CupertinoDialogAction, adaptive property forAlertDialog(#2365).Dismissible.confirmDismissprop (#2359).ListView.reverseandGridView.reverseprops (#2335).Text.styletype Deprecation warning (#2286).- Add
LineChartData.prevent_curve_over_shootingandLineChartData.prevent_curve_over_shooting_thresholdprops (#2354). flet buildto add checks to allow certain build commands according to "build_on" platform (#2343).- Fixed:
flet buildgives "OSError: [WinError 193] %1 is not a valid Win32 application" for some users (#2318). - Fixed: PubSub is not shared between pages in the same FastAPI app (#2368).
- Fixed: check for
DISPLAYinstead ofXDG_CURRENT_DESKTOPto check if linux machine is GUIless or not (#2373).
-
0.18.030 Dec 2023Release notes
Open source →flet buildcommand to package Flet app for any platform (docs).- Added TextStyle for the Text control (#2270).
- Refactor code, add Enum deprecation utils (#2259).
CupertinoAppBarcontrol (#2278).- Fix AlertDialog content updating (#2277).
- Fix FLET_VIEW_PATH ignored on linux (#2244).
MenuBar,SubMenuButtonandMenuItemButtoncontrols (#2252).- convert 'key' to a super parameter (#2258).
-
0.17.018 Dec 2023 -
0.16.014 Dec 2023Release notes
Open source →CupertinoSlidercontrol andSlider.adaptive(#2224).CupertinoRadiocontrol andRadio.adaptive(#2225).- Fix
NavigationBar.label_behavior(#2229). CupertinoSwitchcontrol (docs).- Disable fade-in effect on Flet app start.
- Tab alignment bug fix (#2208).
- Tab visibility (#2213).
- Dark window title for Windows (#2204).
- Fix
ValueErroron web page resize (#1564).
-
0.15.004 Dec 2023Release notes
Open source →ExpansionPanelandExpansionPanelListcontrols (docs).CupertinoCheckBoxcontrol, adaptiveCheckBox(docs).- Additional control props (#2182):
Card.shape.NavigationDestination.tooltip.NavigationRail:elevation,indicator_color,indicator_shape.BottomSheet:bgcolor,elevation.
- Added
Dropdown.Option.visibleproperty. - Fix AlertDialog broken content when testing in Flet app (#2192).
-
0.14.029 Nov 2023 -
0.13.024 Nov 2023 -
0.12.217 Nov 2023