<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://flet.dev/blog</id>
    <title>Flet Blog</title>
    <updated>2026-04-01T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://flet.dev/blog"/>
    <subtitle>Flet Blog</subtitle>
    <icon>https://flet.dev/img/favicon.ico</icon>
    <entry>
        <title type="html"><![CDATA[Flet 0.84.0: Goodbye MkDocs, hello CrocoDocs!]]></title>
        <id>https://flet.dev/blog/flet-v-0-84-release-announcement</id>
        <link href="https://flet.dev/blog/flet-v-0-84-release-announcement"/>
        <updated>2026-04-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flet 0.84.0 is a developer-experience release: new documentation website and re-worked examples.]]></summary>
        <content type="html"><![CDATA[<p>Flet 0.84.0 is a developer-experience release: new documentation website and re-worked examples.</p>
<p>Highlights in this release:</p>
<ul>
<li class="">Flet docs are back on Docusaurus - fast dev server, working hot reload, unified website.</li>
<li class="">Meet CrocoDocs, our new tool that bridges Python docstrings and Docusaurus.</li>
<li class="">All 466 Flet examples migrated to standalone projects with rich metadata for Gallery and AI discovery.</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="how-to-upgrade">How to upgrade<a href="https://flet.dev/blog/flet-v-0-84-release-announcement#how-to-upgrade" class="hash-link" aria-label="Direct link to How to upgrade" title="Direct link to How to upgrade" translate="no">​</a></h2>
<p>If you use pip:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pip install 'flet[all]' --upgrade</span><br></span></code></pre></div></div>
<p>If you use uv with <code>pyproject.toml</code> and want to upgrade everything:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">uv sync --upgrade</span><br></span></code></pre></div></div>
<p>If you want to upgrade only Flet packages:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">uv sync --upgrade-package flet \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  --upgrade-package flet-cli \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  --upgrade-package flet-desktop \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  --upgrade-package flet-web</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="goodbye-mkdocs-hello-crocodocs">Goodbye, MkDocs! Hello, CrocoDocs!<a href="https://flet.dev/blog/flet-v-0-84-release-announcement#goodbye-mkdocs-hello-crocodocs" class="hash-link" aria-label="Direct link to Goodbye, MkDocs! Hello, CrocoDocs!" title="Direct link to Goodbye, MkDocs! Hello, CrocoDocs!" translate="no">​</a></h2>
<p>The Flet website has always been built on <a href="https://docusaurus.io/" target="_blank" rel="noopener noreferrer" class="">Docusaurus</a> - it's fast, extensible, and has great MDX support. But we were authoring API docs manually, which caused synchronization issues with the source code and a lot of duplication: we'd write the same content in Python docstrings and then again in Docusaurus pages.</p>
<p>For Flet "v1", <a href="https://github.com/ndonkoHenri" target="_blank" rel="noopener noreferrer" class="">@ndonkoHenri</a> made a huge push by moving all API docs into Python docstrings and configuring <a href="https://www.mkdocs.org/" target="_blank" rel="noopener noreferrer" class="">MkDocs</a> + <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener noreferrer" class="">Material for MkDocs</a> + <a href="https://mkdocstrings.github.io/" target="_blank" rel="noopener noreferrer" class="">mkdocstrings</a> to serve Flet documentation. It was a great and timely decision to make docstrings the single source of truth.</p>
<p>And it worked, but with some quirks:</p>
<ul>
<li class="">Flet has a large codebase with many cross-references. The docs dev server took <strong>around 3 minutes</strong> to start.</li>
<li class="">For <a href="https://github.com/mkdocs/mkdocs/issues/4032" target="_blank" rel="noopener noreferrer" class="">some</a> <a href="https://github.com/squidfunk/mkdocs-material/issues/8478" target="_blank" rel="noopener noreferrer" class="">reason</a>, hot reload was not working - which meant making a change, restarting, and waiting another 3 minutes to see the result!</li>
</ul>
<p>Then, one day, we saw this warning in a build log and got a feeling that something was off:</p>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>warning</div><div class="admonitionContent_BuS1"><p>WARNING - MkDocs 2.0 is incompatible with Material for MkDocs</p></div></div>
<p>Apparently, there is a <a href="https://fpgmaas.com/blog/collapse-of-mkdocs/" target="_blank" rel="noopener noreferrer" class="">whole story</a> that has been developing for a few years. The short version: the MkDocs original author started working on MkDocs 2.0 which drops plugin support and is not compatible with MkDocs 1.x. The Material for MkDocs team started working on <a href="https://zensical.io/" target="_blank" rel="noopener noreferrer" class="">Zensical</a>, a MkDocs rewrite in Rust that is backward-compatible but launched with many plugins still missing.</p>
<p>We decided to bring docs back to Docusaurus - but this time with a tool that keeps docstrings as the single source of truth.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="meet-crocodocs">Meet CrocoDocs<a href="https://flet.dev/blog/flet-v-0-84-release-announcement#meet-crocodocs" class="hash-link" aria-label="Direct link to Meet CrocoDocs" title="Direct link to Meet CrocoDocs" translate="no">​</a></h3>
<img src="https://flet.dev/img/blog/flet-0-84/crocodocs-logo.png" class="screenshot-40">
<p>CrocoDocs is our home-grown tool that transforms Flet API data into a form that Docusaurus can render. The idea is simple: extract API information from Python docstrings using <a href="https://mkdocstrings.github.io/griffe/" target="_blank" rel="noopener noreferrer" class="">Griffe</a>, produce JSON data and MDX partials, and let Docusaurus render everything using custom MDX components and remark plugins.</p>
<p>The pipeline looks like this:</p>
<ol>
<li class=""><strong>Extract</strong> - Griffe parses all Python packages and collects classes, functions, docstrings, and type annotations.</li>
<li class=""><strong>Transform</strong> - CrocoDocs builds an <code>api-data.json</code> with all API entries and a cross-reference map (<code>xref_map</code>) that resolves symbol names to documentation URLs.</li>
<li class=""><strong>Generate</strong> - MDX partials are produced for CLI docs, permissions, and the PyPI package index. Code examples are indexed from the examples directory.</li>
<li class=""><strong>Render</strong> - Docusaurus picks up the generated data and a custom remark plugin resolves cross-references into clickable links.</li>
</ol>
<p>It's a modern Python project, managed with uv and configured entirely via <code>pyproject.toml</code>.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="new-cross-reference-format">New cross-reference format<a href="https://flet.dev/blog/flet-v-0-84-release-announcement#new-cross-reference-format" class="hash-link" aria-label="Direct link to New cross-reference format" title="Direct link to New cross-reference format" translate="no">​</a></h3>
<p>We switched from <a href="https://analog-garage.github.io/mkdocstrings-python-xref/latest/" target="_blank" rel="noopener noreferrer" class="">mkdocstrings-python-xref</a> format to reST-style roles in docstrings. This was a deliberate choice: reST roles are a well-known standard, and - crucially - they are navigable in VS Code and other editors that render docstring tooltips.</p>
<p>Before (mkdocstrings):</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">"""See [Page][flet.] and [Control.visible][flet.] for details."""</span><br></span></code></pre></div></div>
<p>After (reST roles):</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">"""See :class:`~flet.Page` and :attr:`flet.Control.visible` for details."""</span><br></span></code></pre></div></div>
<p>The supported roles are <code>:class:</code>, <code>:attr:</code>, <code>:meth:</code>, <code>:func:</code>, <code>:mod:</code>, <code>:data:</code>, and <code>:obj:</code>. The <code>~</code> prefix shortens the display name - <code>:class:</code>~flet.Page`` renders as just "Page" while still linking to the full path.</p>
<p>Here's what it looks like in VS Code - docstring links are rendered and navigable right in the tooltip:</p>
<img src="https://flet.dev/img/blog/flet-0-84/vscode-docstring.png" class="screenshot-80 screenshot-rounded">
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="strict-ci-checks">Strict CI checks<a href="https://flet.dev/blog/flet-v-0-84-release-announcement#strict-ci-checks" class="hash-link" aria-label="Direct link to Strict CI checks" title="Direct link to Strict CI checks" translate="no">​</a></h3>
<p>In addition to the broken-link checks that Docusaurus performs during build, we added a custom CI script with strict validation:</p>
<ul>
<li class=""><strong>Broken images</strong> - verifies that every <code>&lt;img src="..."&gt;</code> points to an existing file.</li>
<li class=""><strong>Unresolved reST xrefs</strong> - catches any <code>:class:</code>, <code>:attr:</code>, <code>:meth:</code> markers that were not resolved to links.</li>
<li class=""><strong>Missing code examples</strong> - flags <code>&lt;CodeExample&gt;</code> components that reference non-existent example files.</li>
<li class=""><strong>Missing API entries</strong> - detects symbols referenced in docs but absent from <code>api-data.json</code>.</li>
</ul>
<p>If any check fails, the build fails. No broken docs make it to production.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="the-results">The results<a href="https://flet.dev/blog/flet-v-0-84-release-announcement#the-results" class="hash-link" aria-label="Direct link to The results" title="Direct link to The results" translate="no">​</a></h3>
<p>The migration from MkDocs to Docusaurus brought exactly what we hoped for:</p>
<ul>
<li class="">The generate phase and Docusaurus dev server <strong>start in a few seconds</strong> (down from ~3 minutes).</li>
<li class=""><strong>Hot reload works.</strong> Change a page, save, see the update.</li>
<li class="">A <strong>single unified website</strong> for the landing page and docs, with a modern design.</li>
<li class=""><strong>Full-text search with Algolia.</strong></li>
<li class="">A tool we own and can evolve as Flet grows.</li>
</ul>
<p>CrocoDocs is not yet available on PyPI, but if you'd like to adopt it for your Python project - let me know!</p>
<p>More info:</p>
<ul>
<li class="">PR: <a href="https://github.com/flet-dev/flet/pull/6359" target="_blank" rel="noopener noreferrer" class="">#6359</a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="examples-migrated-to-projects">Examples migrated to projects<a href="https://flet.dev/blog/flet-v-0-84-release-announcement#examples-migrated-to-projects" class="hash-link" aria-label="Direct link to Examples migrated to projects" title="Direct link to Examples migrated to projects" translate="no">​</a></h2>
<p>Every Flet example is now a standalone project with its own <code>pyproject.toml</code> and rich metadata. Here's why we made this change:</p>
<p><strong>Better discovery.</strong> Each project carries structured metadata - categories, description, keywords, a list of controls used, complexity level, and more. We need this data for building Gallery v2 (available on the website and as a Flet app) and for building the index for Flet MCP, so AI assistants can find the right example for you.</p>
<p><strong>Easier to build and run.</strong> Previously, if you wanted to try an example, you'd copy it into your own project, figure out the dependencies, and wire things up. Now every example is a complete project you can clone and run directly with <code>flet run</code>.</p>
<p><strong>Self-contained.</strong> Every project includes all its dependencies (<code>flet_charts</code>, <code>flet_map</code>, etc.), permissions, bundle IDs, and assets needed to successfully build and run on any platform.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="what-a-project-looks-like">What a project looks like<a href="https://flet.dev/blog/flet-v-0-84-release-announcement#what-a-project-looks-like" class="hash-link" aria-label="Direct link to What a project looks like" title="Direct link to What a project looks like" translate="no">​</a></h3>
<p>Before - a flat Python file with no metadata:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">sdk/python/examples/controls/</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">├── button_examples.py</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">├── canvas_examples.py</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">└── ...</span><br></span></code></pre></div></div>
<p>After - a structured project directory:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">sdk/python/examples/controls/</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">├── button/</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│   ├── basic/</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│   │   ├── main.py</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│   │   └── pyproject.toml</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│   ├── icons/</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│   │   ├── main.py</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│   │   └── pyproject.toml</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│   └── styling/</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│       ├── main.py</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│       └── pyproject.toml</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">├── canvas/</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│   ├── bezier_curves/</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│   ├── brush/</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│   └── ...</span><br></span></code></pre></div></div>
<p>Each <code>pyproject.toml</code> includes Gallery and MCP metadata:</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[project]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">name = "button-basic"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">version = "1.0.0"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">description = "Basic enabled and disabled Button examples."</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">keywords = ["button", "material", "basic", "disabled"]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">dependencies = ["flet"]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.gallery]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">categories = ["Buttons/Button"]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.metadata]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">title = "Basic button"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">controls = ["SafeArea", "Column", "Button"]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">layout_pattern = "inline-actions"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">complexity = "basic"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">features = ["enabled and disabled states"]</span><br></span></code></pre></div></div>
<p>In total, <strong>466 examples</strong> were migrated to this format.</p>
<p>More info:</p>
<ul>
<li class="">PR: <a href="https://github.com/flet-dev/flet/pull/6355" target="_blank" rel="noopener noreferrer" class="">#6355</a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="conclusion">Conclusion<a href="https://flet.dev/blog/flet-v-0-84-release-announcement#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>Flet 0.84.0 is about the ecosystem around the framework: better docs, better examples, better tooling. CrocoDocs gives us a documentation pipeline we can trust and evolve. Standalone example projects make every sample discoverable, runnable, and ready for AI-assisted workflows.</p>
<p>Try it and share feedback in <a href="https://github.com/flet-dev/flet/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a> or on <a href="https://discord.gg/dzWXP8SHG8" target="_blank" rel="noopener noreferrer" class="">Discord</a>.</p>
<p>Happy Flet-ing!</p>]]></content>
        <author>
            <name>Feodor Fitsner</name>
            <uri>ttps://github.com/FeodorFitsner</uri>
        </author>
        <category label="releases" term="releases"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Flet 0.83.0: Faster diffs, leaner packages, road to 1.0]]></title>
        <id>https://flet.dev/blog/flet-v-0-83-release-announcement</id>
        <link href="https://flet.dev/blog/flet-v-0-83-release-announcement"/>
        <updated>2026-03-26T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flet 0.83.0 is here with major performance gains, a reworked packaging pipeline, and better project transparency - all part of our push toward a rock-solid 1.0.]]></summary>
        <content type="html"><![CDATA[<p>Flet 0.83.0 is here with major performance gains, a reworked packaging pipeline, and better project transparency - all part of our push toward a rock-solid 1.0.</p>
<p>Highlights in this release:</p>
<ul>
<li class="">Up to 6.7× faster control diffing for both imperative and declarative apps.</li>
<li class="">Smarter <code>.update()</code> logic that eliminates redundant updates.</li>
<li class="">Declarative field validation with <code>Annotated</code> types.</li>
<li class="">Desktop binaries and build templates moved from PyPI to GitHub Releases - smaller installs, pinned versions.</li>
<li class="">Better release traceability with milestones and pre-releases on GitHub.</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="how-to-upgrade">How to upgrade<a href="https://flet.dev/blog/flet-v-0-83-release-announcement#how-to-upgrade" class="hash-link" aria-label="Direct link to How to upgrade" title="Direct link to How to upgrade" translate="no">​</a></h2>
<p>If you use pip:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pip install 'flet[all]' --upgrade</span><br></span></code></pre></div></div>
<p>If you use uv with <code>pyproject.toml</code> and want to upgrade everything:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">uv sync --upgrade</span><br></span></code></pre></div></div>
<p>If you want to upgrade only Flet packages:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">uv sync --upgrade-package flet \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  --upgrade-package flet-cli \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  --upgrade-package flet-desktop \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  --upgrade-package flet-web</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="faster-control-diffing">Faster control diffing<a href="https://flet.dev/blog/flet-v-0-83-release-announcement#faster-control-diffing" class="hash-link" aria-label="Direct link to Faster control diffing" title="Direct link to Faster control diffing" translate="no">​</a></h2>
<p>Every time your app calls <code>page.update()</code> or rebuilds a declarative component, Flet computes a diff - the set of property changes to send to Flutter. In 0.83.0 we overhauled this mechanism for both programming styles, and the results are dramatic.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="imperative-apps">Imperative apps<a href="https://flet.dev/blog/flet-v-0-83-release-announcement#imperative-apps" class="hash-link" aria-label="Direct link to Imperative apps" title="Direct link to Imperative apps" translate="no">​</a></h3>
<p><strong>Before:</strong> every <code>page.update()</code> walked through <em>all</em> properties of every control and compared them to the previous snapshot - even properties you never touched. If your control has 20 properties and you changed one, Flet still compared all 20.</p>
<p><strong>After:</strong> a new <code>Prop</code> descriptor tracks which properties were actually written since the last diff. When you set <code>button.text = "Click me"</code>, only <code>text</code> is flagged as dirty. On the next <code>page.update()</code>, Flet sends only the dirty properties to Flutter and skips the rest. Think of it like only checking the light switches you actually flipped, instead of walking through every room in the house.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="declarative-apps">Declarative apps<a href="https://flet.dev/blog/flet-v-0-83-release-announcement#declarative-apps" class="hash-link" aria-label="Direct link to Declarative apps" title="Direct link to Declarative apps" translate="no">​</a></h3>
<p><strong>Before:</strong> when a component rebuilt, Flet compared every field of the new control tree against the old one - including nested value objects like <code>Alignment</code>, <code>BorderRadius</code>, and <code>BoxDecoration</code>. Since these objects were recreated on every build, they always looked "new" even when nothing changed.</p>
<p><strong>After:</strong> ~150 data types now use a new <code>@value</code> decorator that makes them comparable by content rather than identity. Combined with a two-pass diff that first checks structural changes and then compares only fields that actually differ, the diff skips unchanged subtrees entirely.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="benchmarks">Benchmarks<a href="https://flet.dev/blog/flet-v-0-83-release-announcement#benchmarks" class="hash-link" aria-label="Direct link to Benchmarks" title="Direct link to Benchmarks" translate="no">​</a></h3>
<p>Measured on Python 3.14.2, Apple Silicon:</p>
<ul>
<li class="">Frozen controls with 20 fields, 2 changed: <strong>3.2–3.4× faster</strong> (100–300 controls).</li>
<li class="">Mixed keyed/unkeyed lists: <strong>1.9–2.0× faster</strong>.</li>
<li class="">Non-frozen rebuilt lists: <strong>2.9–4.5× faster</strong>.</li>
<li class=""><a href="https://github.com/flet-dev/flet/blob/main/sdk/python/examples/apps/declarative/sunflower.py" target="_blank" rel="noopener noreferrer" class="">Sunflower demo</a> (500 seeds): <strong>6.7× faster</strong>.</li>
</ul>
<p>More info:</p>
<ul>
<li class="">PR: <a href="https://github.com/flet-dev/flet/pull/6296" target="_blank" rel="noopener noreferrer" class="">#6296</a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="smarter-update-logic">Smarter <code>.update()</code> logic<a href="https://flet.dev/blog/flet-v-0-83-release-announcement#smarter-update-logic" class="hash-link" aria-label="Direct link to smarter-update-logic" title="Direct link to smarter-update-logic" translate="no">​</a></h2>
<p>In previous versions, Flet automatically called <code>page.update()</code> at the end of every event handler. If your handler already called <code>.update()</code> explicitly - say, to show a spinner before starting work - the framework would fire a second, redundant update at the end. This double-update could cause visual glitches or wasted work.</p>
<p>0.83.0 tracks whether <code>.update()</code> was called during handler execution. If it was, the automatic update at the end is skipped. This also means that apps migrated "as is" from Flet 0.28.3 (where there was no auto-update) will behave as expected without changes.</p>
<p>More info:</p>
<ul>
<li class="">PR: <a href="https://github.com/flet-dev/flet/pull/6298" target="_blank" rel="noopener noreferrer" class="">#6298</a></li>
<li class="">Issue: <a href="https://github.com/flet-dev/flet/issues/6236" target="_blank" rel="noopener noreferrer" class="">#6236</a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="declarative-field-validation">Declarative field validation<a href="https://flet.dev/blog/flet-v-0-83-release-announcement#declarative-field-validation" class="hash-link" aria-label="Direct link to Declarative field validation" title="Direct link to Declarative field validation" translate="no">​</a></h2>
<p>Control fields can now declare validation rules inline using Python's <code>Annotated</code> types and a new <code>V</code> rule set. Instead of writing manual checks in <code>__init__</code> or <code>before_update()</code>, you express constraints declaratively:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> typing </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> Annotated</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> flet</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">core</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">validation </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> V</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">entries</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Annotated</span><span class="token punctuation" style="color:#393A34">[</span><span class="token builtin">list</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> V</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">or_</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">V</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">empty</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> V</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">min_length</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><br></span></code></pre></div></div>
<p>This keeps validation close to the field definition and makes it easier to reason about invariants at a glance. Deprecation warnings also get auto-generated admonitions in the docs, so deprecated fields are clearly flagged without manual documentation effort.</p>
<p>More info:</p>
<ul>
<li class="">PR: <a href="https://github.com/flet-dev/flet/pull/6278" target="_blank" rel="noopener noreferrer" class="">#6278</a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="packaging-client-binaries-to-github-releases">Packaging: client binaries to GitHub Releases<a href="https://flet.dev/blog/flet-v-0-83-release-announcement#packaging-client-binaries-to-github-releases" class="hash-link" aria-label="Direct link to Packaging: client binaries to GitHub Releases" title="Direct link to Packaging: client binaries to GitHub Releases" translate="no">​</a></h2>
<p>Until now, Flet desktop binaries (the Flutter client for Windows, macOS, and Linux) were bundled inside PyPI wheels. This made the wheels large and consumed significant PyPI storage. We can't ask PyPI team for storage increase forever! 😊</p>
<p>Starting with 0.83.0, the desktop client is downloaded on first run from GitHub Releases and cached locally at <code>~/.flet/client/</code>. The <code>flet-desktop</code> package is now a single, tiny, platform-independent wheel.</p>
<p>What this means for you:</p>
<ul>
<li class=""><strong>Faster installs.</strong> <code>pip install flet</code> downloads a small wheel instead of a platform-specific binary.</li>
<li class=""><strong>One package.</strong> The separate <code>flet-desktop-light</code> package is gone - choose the "light" or "full" flavor via <code>FLET_DESKTOP_FLAVOR</code> env var or <code>[tool.flet]</code> in <code>pyproject.toml</code>. On Linux the "light" flavor is used by default if not specified.</li>
<li class=""><strong>Air-gapped setups.</strong> Set <code>FLET_CLIENT_URL</code> to point at a local mirror if your environment can't reach GitHub.</li>
</ul>
<p>More info:</p>
<ul>
<li class="">PR: <a href="https://github.com/flet-dev/flet/pull/6309" target="_blank" rel="noopener noreferrer" class="">#6309</a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="packaging-templates-to-github-releases">Packaging: templates to GitHub Releases<a href="https://flet.dev/blog/flet-v-0-83-release-announcement#packaging-templates-to-github-releases" class="hash-link" aria-label="Direct link to Packaging: templates to GitHub Releases" title="Direct link to Packaging: templates to GitHub Releases" translate="no">​</a></h2>
<p>The <code>flet-build-template</code> and <code>flet-app-templates</code> repositories have been consolidated into the main Flet monorepo and are now distributed as zip archives attached to each GitHub Release.</p>
<p>When you run <code>flet build</code> or <code>flet create</code>, the CLI downloads the template zip that matches your installed Flet version. <strong>Versions are pinned</strong> - even for pre-releases - so you always get templates compatible with your Flet version. No more mismatches between the framework and the build template.</p>
<p>For stable releases, the <code>flet</code> Flutter package is published to pub.dev as usual. For pre-releases, the build template references the exact commit SHA via a Git dependency - so <code>flet build</code> always compiles against the precise Flutter code that matches your Python package.</p>
<p>More info:</p>
<ul>
<li class="">PR: <a href="https://github.com/flet-dev/flet/pull/6331" target="_blank" rel="noopener noreferrer" class="">#6331</a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="better-release-traceability">Better release traceability<a href="https://flet.dev/blog/flet-v-0-83-release-announcement#better-release-traceability" class="hash-link" aria-label="Direct link to Better release traceability" title="Direct link to Better release traceability" translate="no">​</a></h2>
<p>We've improved how you can track what's in each release:</p>
<ul>
<li class=""><strong>Pre-releases on GitHub.</strong> Every dev build now creates a <a href="https://github.com/flet-dev/flet/releases" target="_blank" rel="noopener noreferrer" class="">GitHub Release</a> (e.g., <code>v0.83.0.dev6045</code>). You can browse pre-releases to see exactly which fixes and features landed in each build - no more guessing whether your bug fix is in the latest dev version.</li>
<li class=""><strong>Milestones on issues and PRs.</strong> Issues and pull requests are now assigned to <a href="https://github.com/flet-dev/flet/milestones?state=closed" target="_blank" rel="noopener noreferrer" class="">milestones</a>. Want to know when your issue was fixed? Check the milestone - it tells you the release version.</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="road-to-10">Road to 1.0<a href="https://flet.dev/blog/flet-v-0-83-release-announcement#road-to-10" class="hash-link" aria-label="Direct link to Road to 1.0" title="Direct link to Road to 1.0" translate="no">​</a></h2>
<p>We're working hard to make Flet a scalable, sustainable framework, and 0.83.0 reflects that commitment.</p>
<p><strong>Everything is automated.</strong> Our CI pipeline handles building, testing, packaging, and publishing end-to-end. Every push to <code>main</code> triggers a full build of all platform binaries, runs the test suite, executes <code>flet build</code> for all targets, and publishes dev releases to GitHub and pub.dev. There are no manual steps.</p>
<p><strong>Comprehensive integration testing.</strong> We now run 200+ integration tests on macOS across 12 parallel test suites - covering core controls, Material and Cupertino widgets, services, themes, extensions, and example apps. A full run takes about 85 minutes and catches regressions before they reach you. Integration suites for other platforms are coming!</p>
<p><strong>New documentation is coming.</strong> We're moving back to Docusaurus for the Flet docs, which will bring a better reading experience, improved search, and easier contribution workflow. Stay tuned.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="other-changes-and-bug-fixes">Other changes and bug fixes<a href="https://flet.dev/blog/flet-v-0-83-release-announcement#other-changes-and-bug-fixes" class="hash-link" aria-label="Direct link to Other changes and bug fixes" title="Direct link to Other changes and bug fixes" translate="no">​</a></h2>
<ul>
<li class="">Customizable scrollbars (<a href="https://github.com/flet-dev/flet/issues/6282" target="_blank" rel="noopener noreferrer" class="">#6282</a>).</li>
<li class="">Scrollable <code>ExpansionPanelList</code> (<a href="https://github.com/flet-dev/flet/issues/6294" target="_blank" rel="noopener noreferrer" class="">#6294</a>).</li>
<li class=""><code>SharedPreferences</code> now supports <code>int</code>, <code>float</code>, <code>bool</code>, and <code>list[str]</code> types (<a href="https://github.com/flet-dev/flet/issues/6267" target="_blank" rel="noopener noreferrer" class="">#6267</a>).</li>
<li class="">Align Python defaults with Dart defaults across all packages (<a href="https://github.com/flet-dev/flet/issues/6330" target="_blank" rel="noopener noreferrer" class="">#6330</a>).</li>
<li class="">Fix <code>ReorderableListView</code> event deserialization for <code>on_reorder_start</code>/<code>on_reorder_end</code> (<a href="https://github.com/flet-dev/flet/issues/6315" target="_blank" rel="noopener noreferrer" class="">#6315</a>).</li>
<li class="">Skip micropip load for apps with <code>pyproject.toml</code> (<a href="https://github.com/flet-dev/flet/issues/6300" target="_blank" rel="noopener noreferrer" class="">#6300</a>).</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="conclusion">Conclusion<a href="https://flet.dev/blog/flet-v-0-83-release-announcement#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>Flet 0.83.0 is a release about foundations: faster internals, cleaner packaging, and better tooling. These are the kinds of improvements that compound - every future release builds on a faster, more reliable base.</p>
<p>Try it in your apps and share feedback in <a href="https://github.com/flet-dev/flet/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a> or on <a href="https://discord.gg/dzWXP8SHG8" target="_blank" rel="noopener noreferrer" class="">Discord</a>.</p>
<p>Happy Flet-ing!</p>]]></content>
        <author>
            <name>Feodor Fitsner</name>
            <uri>ttps://github.com/FeodorFitsner</uri>
        </author>
        <category label="releases" term="releases"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Flet 0.81.0: Camera, CodeEditor, color pickers and more]]></title>
        <id>https://flet.dev/blog/flet-v-0-81-release-announcement</id>
        <link href="https://flet.dev/blog/flet-v-0-81-release-announcement"/>
        <updated>2026-02-24T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flet 0.81.0 is now available with new controls, better platform integration, and build workflow improvements.]]></summary>
        <content type="html"><![CDATA[<p>Flet 0.81.0 is now available with new controls, better platform integration, and build workflow improvements.</p>
<p>Highlights in this release:</p>
<ul>
<li class="">New controls: <code>Camera</code>, <code>CodeEditor</code>, <code>PageView</code>, color pickers, <code>RotatedBox</code>.</li>
<li class="">Advanced visual transitions with <code>Hero</code> animations and <code>Matrix4</code> transforms.</li>
<li class="">Better app packaging with <code>flet build ios-simulator</code> and <code>flet build --artifact</code>.</li>
<li class=""><code>Clipboard</code> APIs for images and files.</li>
<li class="">Web <code>FilePicker</code> support for direct file content (<code>with_data=True</code>).</li>
<li class="">Platform locale info and locale change events.</li>
<li class="">New <code>LayoutControl.on_size_change</code> event for size-aware UI.</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="how-to-upgrade">How to upgrade<a href="https://flet.dev/blog/flet-v-0-81-release-announcement#how-to-upgrade" class="hash-link" aria-label="Direct link to How to upgrade" title="Direct link to How to upgrade" translate="no">​</a></h2>
<p>If you use pip:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pip install 'flet[all]' --upgrade</span><br></span></code></pre></div></div>
<p>If you use uv with <code>pyproject.toml</code> and want to upgrade everything:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">uv sync --upgrade</span><br></span></code></pre></div></div>
<p>If you want to upgrade only Flet packages:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">uv sync --upgrade-package flet \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  --upgrade-package flet-cli \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  --upgrade-package flet-desktop \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  --upgrade-package flet-web</span><br></span></code></pre></div></div>
<p>On Linux, your project might use <code>flet-desktop-light</code> instead of <code>flet-desktop</code>. In that case, upgrade <code>flet-desktop-light</code> package instead.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="camera"><code>Camera</code><a href="https://flet.dev/blog/flet-v-0-81-release-announcement#camera" class="hash-link" aria-label="Direct link to camera" title="Direct link to camera" translate="no">​</a></h2>
<p><code>Camera</code> is a new control for live camera preview, image capture, video recording, and frame streaming.</p>
<p>It is currently supported on web, iOS, and Android, which makes it practical for cross-platform scanning, media capture, and computer vision scenarios from a single Flet codebase.</p>
<img src="https://flet.dev/img/blog/flet-0-81/camera.png" class="screenshot-50">
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet_camera </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> fc</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Page</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        fc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Camera</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            expand</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            preview_enabled</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>More info:</p>
<ul>
<li class="">Docs: <a href="https://flet.dev/docs/camera/" target="_blank" rel="noopener noreferrer" class="">https://flet.dev/docs/camera/</a></li>
<li class="">Issue: <a href="https://github.com/flet-dev/flet/issues/6190" target="_blank" rel="noopener noreferrer" class="">#6190</a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="codeeditor"><code>CodeEditor</code><a href="https://flet.dev/blog/flet-v-0-81-release-announcement#codeeditor" class="hash-link" aria-label="Direct link to codeeditor" title="Direct link to codeeditor" translate="no">​</a></h2>
<p><code>CodeEditor</code> brings an embedded source editor into Flet apps.</p>
<p>This is useful for developer tools, education apps, playgrounds, and it is also part of the groundwork for the upcoming FletPad experience.</p>
<img src="https://flet.dev/img/blog/flet-0-81/code-editor.png" class="screenshot-60">
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet_code_editor </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> fce</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Page</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        fce</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">CodeEditor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            language</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">fce</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">CodeLanguage</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">PYTHON</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            code_theme</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">fce</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">CodeTheme</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ATOM_ONE_LIGHT</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            value</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"print('Hello, Flet')"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            expand</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>More info:</p>
<ul>
<li class="">Docs: <a href="https://flet.dev/docs/codeeditor/" target="_blank" rel="noopener noreferrer" class="">https://flet.dev/docs/codeeditor/</a></li>
<li class="">Issue: <a href="https://github.com/flet-dev/flet/issues/6162" target="_blank" rel="noopener noreferrer" class="">#6162</a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="pageview"><code>PageView</code><a href="https://flet.dev/blog/flet-v-0-81-release-announcement#pageview" class="hash-link" aria-label="Direct link to pageview" title="Direct link to pageview" translate="no">​</a></h2>
<p><code>PageView</code> provides swipe-based paging with viewport control and programmatic navigation.</p>
<p>It solves a common mobile-style UX need for onboarding, content carousels, step-by-step flows, and story-like interfaces.</p>
<img src="https://flet.dev/img/blog/flet-0-81/page-view.gif" class="screenshot-50">
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Page</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">PageView</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            expand</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            viewport_fraction</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">0.9</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            selected_index</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            controls</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Container</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    bgcolor</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Colors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">INDIGO_400</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    alignment</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Alignment</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">CENTER</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    content</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Page 1"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> size</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">24</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> color</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Colors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">WHITE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Container</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    bgcolor</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Colors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">PINK_300</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    alignment</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Alignment</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">CENTER</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    content</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Page 2"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> size</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">24</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> color</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Colors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">WHITE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Container</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    bgcolor</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Colors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">TEAL_300</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    alignment</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Alignment</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">CENTER</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    content</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Page 3"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> size</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">24</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> color</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Colors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">WHITE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>More info:</p>
<ul>
<li class="">Docs: <a href="https://flet.dev/docs/controls/pageview/" target="_blank" rel="noopener noreferrer" class="">https://flet.dev/docs/controls/pageview/</a></li>
<li class="">Issue: <a href="https://github.com/flet-dev/flet/issues/6158" target="_blank" rel="noopener noreferrer" class="">#6158</a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="color-pickers">Color pickers<a href="https://flet.dev/blog/flet-v-0-81-release-announcement#color-pickers" class="hash-link" aria-label="Direct link to Color pickers" title="Direct link to Color pickers" translate="no">​</a></h2>
<p>Flet now includes multiple color picker controls powered by <code>flutter_colorpicker</code>.</p>
<p>This makes it easier to build design tools, theming UIs, and customization dialogs without third-party integration work.</p>
<img src="https://flet.dev/img/blog/flet-0-81/color-pickers.png" class="screenshot-60">
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> flet_color_pickers </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> MaterialPicker</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Page</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        MaterialPicker</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            color</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"#ff9800"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            on_color_change</span><span class="token operator" style="color:#393A34">=</span><span class="token keyword" style="color:#00009f">lambda</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">data</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>More info:</p>
<ul>
<li class="">Docs: <a href="https://flet.dev/docs/colorpickers/" target="_blank" rel="noopener noreferrer" class="">https://flet.dev/docs/colorpickers/</a></li>
<li class="">Issue: <a href="https://github.com/flet-dev/flet/issues/6109" target="_blank" rel="noopener noreferrer" class="">#6109</a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="hero-animations"><code>Hero</code> animations<a href="https://flet.dev/blog/flet-v-0-81-release-announcement#hero-animations" class="hash-link" aria-label="Direct link to hero-animations" title="Direct link to hero-animations" translate="no">​</a></h2>
<p><code>Hero</code> animations add shared-element transitions between routes.</p>
<p>They solve abrupt navigation changes by visually connecting matching elements across screens, which improves perceived continuity and polish.</p>
<img src="https://flet.dev/img/blog/flet-0-81/hero.gif" class="screenshot-40">
<p><a href="https://flet.dev/docs/controls/hero/#basic-example" target="_blank" rel="noopener noreferrer" class="">Code example</a></p>
<p>More info:</p>
<ul>
<li class="">Docs: <a href="https://flet.dev/docs/controls/hero/" target="_blank" rel="noopener noreferrer" class="">https://flet.dev/docs/controls/hero/</a></li>
<li class="">Issue: <a href="https://github.com/flet-dev/flet/issues/6157" target="_blank" rel="noopener noreferrer" class="">#6157</a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="matrix4-transforms-and-rotatedbox"><code>Matrix4</code> transforms and <code>RotatedBox</code><a href="https://flet.dev/blog/flet-v-0-81-release-announcement#matrix4-transforms-and-rotatedbox" class="hash-link" aria-label="Direct link to matrix4-transforms-and-rotatedbox" title="Direct link to matrix4-transforms-and-rotatedbox" translate="no">​</a></h2>
<p>This release adds <code>Matrix4</code>-based transforms to <code>LayoutControl.transform</code> and introduces <code>RotatedBox</code>.</p>
<p>Together, they cover both advanced transform pipelines and layout-aware quarter-turn rotation. This helps when building rich interactions, visual effects, and precise UI compositions.</p>
<img src="https://flet.dev/img/blog/flet-0-81/matrix4-transform.png" class="screenshot-80">
<img src="https://flet.dev/img/blog/flet-0-81/rotated-box.png" class="screenshot-20">
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> math </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> pi</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Page</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Container</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">220</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            height</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">130</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            bgcolor</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Colors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">CYAN_300</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            transform</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Transform</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                matrix</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Matrix4</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">identity</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">set_entry</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.0018</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">rotate_y</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">pi </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">8</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">RotatedBox</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">quarter_turns</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> content</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Rotated"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>More info:</p>
<ul>
<li class=""><code>LayoutControl</code> docs: <a href="https://flet.dev/docs/controls/layoutcontrol/" target="_blank" rel="noopener noreferrer" class="">https://flet.dev/docs/controls/layoutcontrol/</a></li>
<li class=""><code>RotatedBox</code> docs: <a href="https://flet.dev/docs/controls/rotatedbox/" target="_blank" rel="noopener noreferrer" class="">https://flet.dev/docs/controls/rotatedbox/</a></li>
<li class="">Issue: <a href="https://github.com/flet-dev/flet/issues/6198" target="_blank" rel="noopener noreferrer" class="">#6198</a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="build-workflow-updates-ios-simulator-target-and-artifact-naming">Build workflow updates: iOS simulator target and artifact naming<a href="https://flet.dev/blog/flet-v-0-81-release-announcement#build-workflow-updates-ios-simulator-target-and-artifact-naming" class="hash-link" aria-label="Direct link to Build workflow updates: iOS simulator target and artifact naming" title="Direct link to Build workflow updates: iOS simulator target and artifact naming" translate="no">​</a></h2>
<p>Packaging for iOS simulator now produces an unsigned <code>.app</code> you can drag and drop into the simulator:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet build ios-simulator</span><br></span></code></pre></div></div>
<p>At the same time, <code>flet build --artifact</code> gives better control over output artifact naming without affecting bundle IDs:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet build macos --artifact "My Awesome App"</span><br></span></code></pre></div></div>
<p>More info:</p>
<ul>
<li class="">iOS simulator build: <a href="https://flet.dev/docs/publish/ios/#flet-build-ios-simulator" target="_blank" rel="noopener noreferrer" class="">https://flet.dev/docs/publish/ios/#flet-build-ios-simulator</a></li>
<li class="">Artifact name docs: <a href="https://flet.dev/docs/publish/#artifact-name" target="_blank" rel="noopener noreferrer" class="">https://flet.dev/docs/publish/#artifact-name</a></li>
<li class="">Issues: <a href="https://github.com/flet-dev/flet/issues/6188" target="_blank" rel="noopener noreferrer" class="">#6188</a>, <a href="https://github.com/flet-dev/flet/issues/6074" target="_blank" rel="noopener noreferrer" class="">#6074</a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="clipboard-filepicker-locales-and-size-aware-layouts"><code>Clipboard</code>, <code>FilePicker</code>, locales, and size-aware layouts<a href="https://flet.dev/blog/flet-v-0-81-release-announcement#clipboard-filepicker-locales-and-size-aware-layouts" class="hash-link" aria-label="Direct link to clipboard-filepicker-locales-and-size-aware-layouts" title="Direct link to clipboard-filepicker-locales-and-size-aware-layouts" translate="no">​</a></h2>
<p>This release improves app integration with operating systems and browsers:</p>
<ul>
<li class=""><code>Clipboard</code> can now get/set images and files.</li>
<li class="">Web <code>FilePicker</code> can return picked file content as <code>bytes</code> with <code>with_data=True</code>.</li>
<li class="">Platform locales and locale change events are available.</li>
<li class=""><code>LayoutControl.on_size_change</code> helps build size-aware UI logic.</li>
</ul>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Page</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">pick_text_file</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">_</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        files </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">FilePicker</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">pick_files</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">with_data</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">files</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">.</span><span class="token builtin">bytes</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> files </span><span class="token keyword" style="color:#00009f">else</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">None</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Button</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Pick file"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> on_click</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">pick_text_file</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Page</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">handle_size_change</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">LayoutSizeChangeEvent</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Container</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        e</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">control</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">content</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">value </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:#e3116c">f"</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation builtin">int</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">(</span><span class="token string-interpolation interpolation">e</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">width</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">)</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c"> x </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation builtin">int</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">(</span><span class="token string-interpolation interpolation">e</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">height</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">)</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Container</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            expand</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            content</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            on_size_change</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">handle_size_change</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>More info:</p>
<ul>
<li class=""><code>Clipboard</code> docs: <a href="https://flet.dev/docs/services/clipboard/" target="_blank" rel="noopener noreferrer" class="">https://flet.dev/docs/services/clipboard/</a></li>
<li class=""><code>FilePicker</code> docs: <a href="https://flet.dev/docs/services/filepicker/" target="_blank" rel="noopener noreferrer" class="">https://flet.dev/docs/services/filepicker/</a></li>
<li class="">Locale type docs: <a href="https://flet.dev/docs/types/locale/" target="_blank" rel="noopener noreferrer" class="">https://flet.dev/docs/types/locale/</a></li>
<li class=""><code>LayoutControl</code> docs: <a href="https://flet.dev/docs/controls/layoutcontrol/" target="_blank" rel="noopener noreferrer" class="">https://flet.dev/docs/controls/layoutcontrol/</a></li>
<li class="">Issues: <a href="https://github.com/flet-dev/flet/issues/6141" target="_blank" rel="noopener noreferrer" class="">#6141</a>, <a href="https://github.com/flet-dev/flet/issues/6199" target="_blank" rel="noopener noreferrer" class="">#6199</a>, <a href="https://github.com/flet-dev/flet/issues/6191" target="_blank" rel="noopener noreferrer" class="">#6191</a>, <a href="https://github.com/flet-dev/flet/issues/6099" target="_blank" rel="noopener noreferrer" class="">#6099</a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="improvements">Improvements<a href="https://flet.dev/blog/flet-v-0-81-release-announcement#improvements" class="hash-link" aria-label="Direct link to Improvements" title="Direct link to Improvements" translate="no">​</a></h2>
<p>0.81.0 reduces memory churn in control diffing algorithm, which is especially important for web apps with frequent UI diffs.</p>
<ul>
<li class="">Optimize <code>object_patch</code> memory churn (<a href="https://github.com/flet-dev/flet/issues/6204" target="_blank" rel="noopener noreferrer" class="">#6204</a>).</li>
<li class="">Add <code>ignore_up_down_keys</code> to <code>TextField</code> and <code>CupertinoTextField</code> (<a href="https://github.com/flet-dev/flet/issues/6183" target="_blank" rel="noopener noreferrer" class="">#6183</a>).</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="other-changes-and-bug-fixes">Other changes and bug fixes<a href="https://flet.dev/blog/flet-v-0-81-release-announcement#other-changes-and-bug-fixes" class="hash-link" aria-label="Direct link to Other changes and bug fixes" title="Direct link to Other changes and bug fixes" translate="no">​</a></h2>
<ul>
<li class="">Bump Flutter to 3.41.2 (italic font finally looks nice!).</li>
<li class="">Register MIME types for <code>.mjs</code> and <code>.wasm</code> (<a href="https://github.com/flet-dev/flet/issues/6140" target="_blank" rel="noopener noreferrer" class="">#6140</a>).</li>
<li class="">Skip component migrate/diff when function signatures differ (<a href="https://github.com/flet-dev/flet/issues/6181" target="_blank" rel="noopener noreferrer" class="">#6181</a>).</li>
<li class="">Fix memory leaks in Flet web app (<a href="https://github.com/flet-dev/flet/issues/6186" target="_blank" rel="noopener noreferrer" class="">#6186</a>).</li>
<li class="">Fix desktop window frameless/titlebar update sync and progress bar clearing (<a href="https://github.com/flet-dev/flet/issues/6114" target="_blank" rel="noopener noreferrer" class="">#6114</a>).</li>
<li class="">Fix first-time button <code>style</code> patching and clear stale style state (<a href="https://github.com/flet-dev/flet/issues/6119" target="_blank" rel="noopener noreferrer" class="">#6119</a>).</li>
<li class="">Fix map layer rebuilds on marker updates (<a href="https://github.com/flet-dev/flet/issues/6113" target="_blank" rel="noopener noreferrer" class="">#6113</a>).</li>
<li class="">Fix <code>AlertDialog</code> and <code>CupertinoAlertDialog</code> barrier color updates (<a href="https://github.com/flet-dev/flet/issues/6097" target="_blank" rel="noopener noreferrer" class="">#6097</a>).</li>
<li class="">Fix <code>ControlEvent</code> runtime type hints (<a href="https://github.com/flet-dev/flet/issues/6102" target="_blank" rel="noopener noreferrer" class="">#6102</a>).</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="flet-app-update-on-mobile-stores"><code>Flet</code> app update on mobile stores<a href="https://flet.dev/blog/flet-v-0-81-release-announcement#flet-app-update-on-mobile-stores" class="hash-link" aria-label="Direct link to flet-app-update-on-mobile-stores" title="Direct link to flet-app-update-on-mobile-stores" translate="no">​</a></h2>
<p>An updated <code>Flet</code> app for testing on mobile devices is coming to the App Store and Google Play soon.</p>
<p>For now, see the current mobile testing guide: <a href="https://flet.dev/docs/getting-started/testing-on-mobile/" target="_blank" rel="noopener noreferrer" class="">https://flet.dev/docs/getting-started/testing-on-mobile/</a></p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="conclusion">Conclusion<a href="https://flet.dev/blog/flet-v-0-81-release-announcement#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>Flet 0.81.0 is focused on practical app-building features: richer UI controls, stronger system integration, and smoother build workflows.</p>
<p>Try it in your apps and share feedback in <a href="https://github.com/flet-dev/flet/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a> or on <a href="https://discord.gg/dzWXP8SHG8" target="_blank" rel="noopener noreferrer" class="">Discord</a>.</p>
<p>Happy Flet-ing!</p>]]></content>
        <author>
            <name>Feodor Fitsner</name>
            <uri>ttps://github.com/FeodorFitsner</uri>
        </author>
        <category label="releases" term="releases"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Flet 1.0 Beta]]></title>
        <id>https://flet.dev/blog/flet-1-0-beta</id>
        <link href="https://flet.dev/blog/flet-1-0-beta"/>
        <updated>2025-12-24T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Today, we're releasing Flet 1.0 Beta, published as version 0.80.0!]]></summary>
        <content type="html"><![CDATA[<p>Today, we're releasing <strong>Flet 1.0 Beta</strong>, published as version 0.80.0!</p>
<p>Flet 1.0 is a huge leap forward! Its goal is to ensure long-term growth, with an architecture designed to scale to larger projects, more users, and an expanding feature set.</p>
<ul>
<li class="">Developers can use either imperative or <a class="" href="https://flet.dev/blog/introducing-declarative-ui-in-flet">declarative style</a> to write their Flet apps.</li>
<li class="">The new <a href="https://flet.dev/docs/" target="_blank" rel="noopener noreferrer" class="">documentation website</a> based on mkdocs, generated from Flet code base and always up-to-date.</li>
<li class="">End-to-end <a href="https://github.com/flet-dev/flet/tree/main/sdk/python/packages/flet/integration_tests" target="_blank" rel="noopener noreferrer" class="">integration tests</a> for all controls and examples.</li>
<li class=""><a href="https://github.com/flet-dev/flet/tree/main/sdk/python/packages" target="_blank" rel="noopener noreferrer" class="">Extensions</a> are back in Flet main repo, with combined docs and covered by tests.</li>
<li class=""><a href="https://github.com/flet-dev/flet/tree/main/sdk/python/examples" target="_blank" rel="noopener noreferrer" class="">Examples</a> are back to main Flet repo, always in sync with Flet API and covered by tests.</li>
<li class=""><a href="https://flet.dev/docs/cli/flet-debug/" target="_blank" rel="noopener noreferrer" class="">flet debug</a> CLI for debugging app on real <a href="https://flet.dev/docs/cli/flet-devices/" target="_blank" rel="noopener noreferrer" class="">devices</a> and <a href="https://flet.dev/docs/cli/flet-emulators/" target="_blank" rel="noopener noreferrer" class="">emulators</a>.</li>
<li class="">Build, test and release <a href="https://github.com/flet-dev/flet/actions" target="_blank" rel="noopener noreferrer" class="">workflows</a> are automated with GitHub Actions.</li>
<li class="">Clean extensibility model with simplified API on Python and Flutter sides.</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="upgrading-to-flet-10-beta">Upgrading to Flet 1.0 Beta<a href="https://flet.dev/blog/flet-1-0-beta#upgrading-to-flet-10-beta" class="hash-link" aria-label="Direct link to Upgrading to Flet 1.0 Beta" title="Direct link to Upgrading to Flet 1.0 Beta" translate="no">​</a></h2>
<p>This release differs from the <a class="" href="https://flet.dev/blog/introducing-flet-1-0-alpha">Alpha</a> in that it is no longer a pre-release (there is no <code>"dev"</code> suffix) and it <strong>replaces</strong> version <strong>0.28.3</strong> as the current release on PyPI.</p>
<p>This means that if you install <code>flet</code> (or any other Flet package), or add it as a dependency <strong>without specifying a version</strong>, you will get <strong>0.80.0</strong> by default.</p>
<p>Why is this important? <strong>0.80.0 is not a drop-in upgrade</strong> — it includes <a href="https://github.com/flet-dev/flet/issues/5238" target="_blank" rel="noopener noreferrer" class="">breaking changes</a>. To run an existing app on <strong>0.80.0</strong>, you will need to migrate it manually.</p>
<p>If you use pip to manage your environment just run:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pip install 'flet[all]' --upgrade</span><br></span></code></pre></div></div>
<p>For projects managed by uv you just remove lock file and re-sync:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">rm uv.lock</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">uv sync</span><br></span></code></pre></div></div>
<p>The latest <code>flet</code> 0.80.x package version will be installed.</p>
<p>Built-in Flet extensions such as <code>flet_audio</code>, <code>flet_video</code>, and others are now published with the same version as the core <code>flet</code> packages, so be sure to update and pin their dependencies as well.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="staying-on-flet-028x">Staying on Flet 0.28.x<a href="https://flet.dev/blog/flet-1-0-beta#staying-on-flet-028x" class="hash-link" aria-label="Direct link to Staying on Flet 0.28.x" title="Direct link to Staying on Flet 0.28.x" translate="no">​</a></h2>
<p>If you do not plan to upgrade your existing app to Flet 1.0, you will need to pin the Flet version to <strong>0.28.3</strong> in your <code>requirements.txt</code> or <code>pyproject.toml</code>:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet==0.28.3</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="flet-app-for-ios-and-android">Flet app for iOS and Android<a href="https://flet.dev/blog/flet-1-0-beta#flet-app-for-ios-and-android" class="hash-link" aria-label="Direct link to Flet app for iOS and Android" title="Direct link to Flet app for iOS and Android" translate="no">​</a></h2>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Work in progress</div><div class="admonitionContent_BuS1"><p>The App Store and Google Play currently host a Flet app built for Flet 0.28.3.
An updated app supporting Flet API 0.80.0 is under development and coming soon.</p><p>Please join the <a href="https://discord.gg/dzWXP8SHG8" target="_blank" rel="noopener noreferrer" class="">Flet Discord server</a> - we'll post an announcement there when a new Flet app becomes available.</p></div></div>
<p><a href="https://flet.dev/docs/getting-started/testing-on-mobile/" target="_blank" rel="noopener noreferrer" class="">Read more about testing on iOS and Android</a>.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="next-steps">Next steps<a href="https://flet.dev/blog/flet-1-0-beta#next-steps" class="hash-link" aria-label="Direct link to Next steps" title="Direct link to Next steps" translate="no">​</a></h2>
<p>If you're starting a new app, we recommend using Flet 0.80.0 (aka "Beta").</p>
<p>"Beta" means the Flet API is 99% stable and will not change before the 1.0 final release. Flet 1.0 Beta is safe for all new applications.</p>
<p>For Flet 0.28.x (also known as <em>Flet v0</em>), we will continue to provide minor updates for bug fixes and security issues, but no new features will be added.</p>
<p>Try Flet 0.80.0 and let us know what you think!</p>
<p>We wish you a Merry Christmas and a Happy New Year! 🎄✨</p>]]></content>
        <author>
            <name>Feodor Fitsner</name>
            <uri>ttps://github.com/FeodorFitsner</uri>
        </author>
        <category label="news" term="news"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Sensor and system services]]></title>
        <id>https://flet.dev/blog/sensor-and-system-services</id>
        <link href="https://flet.dev/blog/sensor-and-system-services"/>
        <updated>2025-12-10T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We've just merged a pull request introducing 10 new device and platform services to the Flet SDK, significantly expanding access to hardware sensors and system capabilities.]]></summary>
        <content type="html"><![CDATA[<p>We've just merged a <a href="https://github.com/flet-dev/flet/pull/5846" target="_blank" rel="noopener noreferrer" class="">pull request</a> introducing 10 new device and platform services to the Flet SDK, significantly expanding access to hardware sensors and system capabilities.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="new-sensor-services">New sensor services<a href="https://flet.dev/blog/sensor-and-system-services#new-sensor-services" class="hash-link" aria-label="Direct link to New sensor services" title="Direct link to New sensor services" translate="no">​</a></h3>
<ul>
<li class=""><a href="https://flet.dev/docs/services/accelerometer/" target="_blank" rel="noopener noreferrer" class="">Accelerometer</a> – Reads raw acceleration along the X, Y, and Z axes, including gravity.</li>
<li class=""><a href="https://flet.dev/docs/services/barometer/" target="_blank" rel="noopener noreferrer" class="">Barometer</a> – Provides atmospheric pressure readings useful for altitude estimation.</li>
<li class=""><a href="https://flet.dev/docs/services/gyroscope/" target="_blank" rel="noopener noreferrer" class="">Gyroscope</a> – Measures device rotation around each axis.</li>
<li class=""><a href="https://flet.dev/docs/services/magnetometer/" target="_blank" rel="noopener noreferrer" class="">Magnetometer</a> – Detects magnetic field strength, commonly used for compass functionality.</li>
<li class=""><a href="https://flet.dev/docs/services/useraccelerometer/" target="_blank" rel="noopener noreferrer" class="">UserAccelerometer</a> – Reports acceleration data with gravity filtered out for cleaner motion detection.</li>
</ul>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="new-system-services">New system services<a href="https://flet.dev/blog/sensor-and-system-services#new-system-services" class="hash-link" aria-label="Direct link to New system services" title="Direct link to New system services" translate="no">​</a></h3>
<ul>
<li class=""><a href="https://flet.dev/docs/services/battery/" target="_blank" rel="noopener noreferrer" class="">Battery</a> – Monitors battery level, charging state, and power source changes.</li>
<li class=""><a href="https://flet.dev/docs/services/connectivity/" target="_blank" rel="noopener noreferrer" class="">Connectivity</a> – Detects network status and connection type (Wi-Fi, mobile, offline).</li>
<li class=""><a href="https://flet.dev/docs/services/screenbrightness/" target="_blank" rel="noopener noreferrer" class="">ScreenBrightness</a> – Allows reading and adjusting the device screen brightness.</li>
<li class=""><a href="https://flet.dev/docs/services/share/" target="_blank" rel="noopener noreferrer" class="">Share</a> – Invokes the system share sheet to share text, files, or URLs.</li>
<li class=""><a href="https://flet.dev/docs/services/wakelock/" target="_blank" rel="noopener noreferrer" class="">Wakelock</a> – Prevents the device screen from dimming or sleeping while active.</li>
</ul>
<img src="https://flet.dev/img/blog/sensors/flet-sensor-services.png" alt="Flet sensor and system services" class="screenshot screenshot-70">
<p>Sensor services mostly work on iOS and Android devices. Using them in a web app is also possible to some extent, but only under specific browser and hardware conditions.</p>
<p>System services are supported on all mobile and desktop platforms.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="how-to-test">How to test<a href="https://flet.dev/blog/sensor-and-system-services#how-to-test" class="hash-link" aria-label="Direct link to How to test" title="Direct link to How to test" translate="no">​</a></h2>
<p>Install the latest <a href="https://pypi.org/project/flet/#history" target="_blank" rel="noopener noreferrer" class="">Flet 0.70.0.devXYZ</a> pre-release.</p>
<p>Use the <a class="" href="https://flet.dev/blog/flet-debug-the-new-cli-for-testing-flet-apps-on-mobile-devices"><code>flet debug</code></a> command to run your app on a real iOS/Android device or emulator.</p>
<p>Testing in the Android emulator is especially convenient, as it allows you to experiment with virtually all available sensors:</p>
<img src="https://flet.dev/img/blog/sensors/flet-sensor-android-emulator.png" alt="Flet sensors testing in Android emulator" class="screenshot screenshot-70">
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="services-api">Services API<a href="https://flet.dev/blog/sensor-and-system-services#services-api" class="hash-link" aria-label="Direct link to Services API" title="Direct link to Services API" translate="no">​</a></h2>
<p>Previously, some services were exposed as page properties, such as <code>page.clipboard</code> or <code>page.shared_preferences</code>.</p>
<p>All services are now standalone and should be used by creating their own instances. For example:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">clipboard </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Clipboard</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> clipboard</span><span class="token punctuation" style="color:#393A34">.</span><span class="token builtin">set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello, world!"</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>or simply:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Clipboard</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token builtin">set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello, world!"</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>When you create a new instance of a service, it is automatically registered within the page and disposed of when it is no longer referenced - for example, at the end of a method call.</p>
<p>However, if you need to assign an event handler to a service that must persist across method calls, you must keep a reference to that service to prevent it from being disposed.</p>
<p>In an imperative Flet app, you can use the <code>page.services</code> list, which holds service instances. For example:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Page</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    battery </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Battery</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">services</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">append</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">battery</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic"># need to keep a reference to the service</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">on_state_change</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">BatteryStateChangeEvent</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string-interpolation string" style="color:#e3116c">f"State changed: </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">e</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">state</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    battery</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">on_state_change </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> on_state_change</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">.</span><br></span></code></pre></div></div>
<p>In a declarative Flet app, you can use the <code>use_ref</code> or <code>use_state</code> hook to hold a service reference. For example:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator annotation punctuation" style="color:#393A34">@ft</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">component</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">App</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">on_state_change</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">BatteryStateChangeEvent</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string-interpolation string" style="color:#e3116c">f"State changed: </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">e</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">state</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">use_ref</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">lambda</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Battery</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">on_state_change</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">on_state_change</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Battery status app"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">lambda</span><span class="token plain"> page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">render</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">App</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>That's all for today, folks! Happy Fletting!</p>]]></content>
        <author>
            <name>Feodor Fitsner</name>
            <uri>ttps://github.com/FeodorFitsner</uri>
        </author>
        <category label="news" term="news"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[flet debug: the new CLI for testing Flet apps on mobile devices]]></title>
        <id>https://flet.dev/blog/flet-debug-the-new-cli-for-testing-flet-apps-on-mobile-devices</id>
        <link href="https://flet.dev/blog/flet-debug-the-new-cli-for-testing-flet-apps-on-mobile-devices"/>
        <updated>2025-12-02T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flet provides "Flet" app, for both iOS and Android, to "experience" your app on a real device. While using Flet app your Python app is still running on your computer and UI changes are streamed to a mobile device. While this approach is fast and convenient it has limitations: the app is able to only use sensors,libraries and permissions coming with Flet app and you can't know whether the app and all its dependencies are going to work when packaged and executed by a Python mobile runtime.]]></summary>
        <content type="html"><![CDATA[<p>Flet provides <a href="https://flet.dev/docs/getting-started/testing-on-mobile/" target="_blank" rel="noopener noreferrer" class="">"Flet" app</a>, for both iOS and Android, to "experience" your app on a real device. While using Flet app your Python app is still running on your computer and UI changes are streamed to a mobile device. While this approach is fast and convenient it has limitations: the app is able to only use sensors,libraries and permissions coming with Flet app and you can't know whether the app and all its dependencies are going to work when packaged and executed by a Python mobile runtime.</p>
<p>In the latest Flet v1 pre-release we have introduced three new Flet CLI commands to package and run Flet app on a real device or emulator:</p>
<ul>
<li class=""><a href="https://flet.dev/docs/cli/flet-debug/" target="_blank" rel="noopener noreferrer" class=""><code>flet debug</code></a> - to run Flet app on a device or emulator.</li>
<li class=""><a href="https://flet.dev/docs/cli/flet-devices/" target="_blank" rel="noopener noreferrer" class=""><code>flet devices</code></a> - to list connected devices.</li>
<li class=""><a href="https://flet.dev/docs/cli/flet-emulators/" target="_blank" rel="noopener noreferrer" class=""><code>flet emulators</code></a> - to list iOS/Android emulators and manage Android emulators.</li>
</ul>
<p>This is a screenshot of a simple Flet app running on my iPhone:</p>
<img src="https://flet.dev/img/blog/flet-debug/flet-debug-on-real-iphone.png" alt="flet debug CLI on a real device" class="screenshot screenshot-rounded">
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="how-to-use">How to use<a href="https://flet.dev/blog/flet-debug-the-new-cli-for-testing-flet-apps-on-mobile-devices#how-to-use" class="hash-link" aria-label="Direct link to How to use" title="Direct link to How to use" translate="no">​</a></h2>
<p>Run this command to list all connected iOS/Android devices and emulators:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet devices</span><br></span></code></pre></div></div>
<p>If you see empty list make sure emulator is running or device connected.</p>
<p>Copy device ID you'd like to run your app on.</p>
<p>Run the following command to build Flet app and run on your device:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet debug &lt;ios|android&gt; --device-id &lt;device_id&gt; -v</span><br></span></code></pre></div></div>
<blockquote>
<p>You can omit <code>-v</code> option next time you run the command, if everything worked OK.</p>
</blockquote>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="testing-on-android-emulator">Testing on Android emulator<a href="https://flet.dev/blog/flet-debug-the-new-cli-for-testing-flet-apps-on-mobile-devices#testing-on-android-emulator" class="hash-link" aria-label="Direct link to Testing on Android emulator" title="Direct link to Testing on Android emulator" translate="no">​</a></h2>
<p>To list available iOS and Android emulators run this command:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet emulators</span><br></span></code></pre></div></div>
<blockquote>
<p>This command requires Android SDK - you will be asked to install/update it.</p>
</blockquote>
<p>To create a new Android emulator run:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet emulators create my-emulator</span><br></span></code></pre></div></div>
<p>To start an emulator:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet emulators start my-emulator</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="testing-on-iosipados-emulator">Testing on iOS/iPadOS emulator<a href="https://flet.dev/blog/flet-debug-the-new-cli-for-testing-flet-apps-on-mobile-devices#testing-on-iosipados-emulator" class="hash-link" aria-label="Direct link to Testing on iOS/iPadOS emulator" title="Direct link to Testing on iOS/iPadOS emulator" translate="no">​</a></h2>
<p>To create a new iOS/iPadOS simulator:</p>
<p>List simulator models:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">xcrun simctl list devicetypes</span><br></span></code></pre></div></div>
<p>List available runtimes:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">xcrun simctl list runtimes</span><br></span></code></pre></div></div>
<p>Create simulator:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">xcrun simctl create "&lt;Name&gt;" "&lt;Device Type&gt;" "&lt;Runtime&gt;"</span><br></span></code></pre></div></div>
<p>For example:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">xcrun simctl create "My iPhone 17 Pro" "iPhone 17 Pro" com.apple.CoreSimulator.SimRuntime.iOS-26-1</span><br></span></code></pre></div></div>
<p>Start Apple Simulator with:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">open -a Simulator</span><br></span></code></pre></div></div>
<p>Open "File -&gt; Open Simulator -&gt; <code>&lt;Your Simulator&gt;</code>".</p>
<p>Run this command to get simulator device ID:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet devices</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="testing-on-a-real-iphoneipad-device">Testing on a real iPhone/iPad device<a href="https://flet.dev/blog/flet-debug-the-new-cli-for-testing-flet-apps-on-mobile-devices#testing-on-a-real-iphoneipad-device" class="hash-link" aria-label="Direct link to Testing on a real iPhone/iPad device" title="Direct link to Testing on a real iPhone/iPad device" translate="no">​</a></h2>
<ul>
<li class="">Enable developer mode on your device.</li>
<li class="">Connect the device with USB cable. You can use debug via Wi-Fi, but it's significantly slower than via cable.</li>
<li class="">Open XCode, go to "Window -&gt; Devices and Simulators". Wait until "device support files" are copied - it could take a few minutes.</li>
</ul>
<blockquote>
<p>When you connect an iOS device and open Xcode, it automatically downloads “device support” and symbol files from the iPhone. These files allow Xcode (and Flutter) to understand the exact iOS version on the device and provide fast, reliable debugging. Without them, Xcode can’t map system libraries correctly, which leads to slow startup, missing breakpoints, or warnings like “LLDB could not find the on-disk shared cache.” This setup happens only once per iOS version and is required for running or debugging apps on a physical device.</p>
</blockquote>
<ul>
<li class="">Create a new <a href="https://flet.dev/docs/publish/ios/#provisioning-profile" target="_blank" rel="noopener noreferrer" class="">provisioning profile</a> that includes your device ID and developer certificate.</li>
<li class="">Configure app bundle ID and "debugging" profile in <code>pyproject.toml</code>:</li>
</ul>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.ios]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">bundle_id = "com.your-company.app"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.ios.export_methods."debugging"]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">provisioning_profile = "Development com.your-company.app"</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="faq">FAQ<a href="https://flet.dev/blog/flet-debug-the-new-cli-for-testing-flet-apps-on-mobile-devices#faq" class="hash-link" aria-label="Direct link to FAQ" title="Direct link to FAQ" translate="no">​</a></h2>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="does-flet-debug-replace-flet-mobile-app">Does <code>flet debug</code> replace "Flet" mobile app?<a href="https://flet.dev/blog/flet-debug-the-new-cli-for-testing-flet-apps-on-mobile-devices#does-flet-debug-replace-flet-mobile-app" class="hash-link" aria-label="Direct link to does-flet-debug-replace-flet-mobile-app" title="Direct link to does-flet-debug-replace-flet-mobile-app" translate="no">​</a></h3>
<p>No. "Flet" app will stay there and will be updated by Flet v1 Beta release.</p>
<p>"Flet" app allows quickly experience your app on a mobile device, but with limited capabilities (not all permissions are enabled and the app itself is running on your computer).</p>
<p><code>flet debug</code> allows running on emulator or a real device without making IPA/APK package and manually uploading it to a device. Your entire app is packaged and run on a device. You can customize permissions and other settings in <code>pyproject.toml</code>.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="when-is-stable-flet-v1-going-to-be-released">When is stable Flet v1 going to be released?<a href="https://flet.dev/blog/flet-debug-the-new-cli-for-testing-flet-apps-on-mobile-devices#when-is-stable-flet-v1-going-to-be-released" class="hash-link" aria-label="Direct link to When is stable Flet v1 going to be released?" title="Direct link to When is stable Flet v1 going to be released?" translate="no">​</a></h3>
<p>We are going to release a stable Flet v1 Beta before Christmas.</p>
<p>Best regards and happy Fletting!</p>]]></content>
        <author>
            <name>Feodor Fitsner</name>
            <uri>ttps://github.com/FeodorFitsner</uri>
        </author>
        <category label="news" term="news"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Introducing Declarative UI in Flet]]></title>
        <id>https://flet.dev/blog/introducing-declarative-ui-in-flet</id>
        <link href="https://flet.dev/blog/introducing-declarative-ui-in-flet"/>
        <updated>2025-10-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flet 1.0 is about more than a facelift. Our goal is to help Python developers build production-grade apps that scale from a handful of screens to hundreds of pages, views, and dialogs.]]></summary>
        <content type="html"><![CDATA[<p>Flet 1.0 is about more than a facelift. Our goal is to help Python developers build production-grade apps that scale from a handful of screens to hundreds of pages, views, and dialogs.</p>
<p>Dogfooding Flet — building our own products like the Flet mobile app and the Control Gallery — made it clear that the imperative approach becomes hard to manage as apps grow.</p>
<p>That’s why Flet 1.0 introduces a declarative approach alongside the existing imperative API, drawing inspiration from frameworks such as React, SwiftUI, and Jetpack Compose.</p>
<p>Here's a quick look at a counter app written declaratively:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator annotation punctuation" style="color:#393A34">@ft</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">component</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">App</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    count</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> set_count </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">use_state</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Row</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        controls</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token operator" style="color:#393A34">=</span><span class="token string-interpolation string" style="color:#e3116c">f"</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">count</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Button</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Add"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> on_click</span><span class="token operator" style="color:#393A34">=</span><span class="token keyword" style="color:#00009f">lambda</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> set_count</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">count </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">lambda</span><span class="token plain"> page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">render</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">App</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>Keep reading to see how it works and how you can start using it today.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="what-is-imperative-ui">What is imperative UI<a href="https://flet.dev/blog/introducing-declarative-ui-in-flet#what-is-imperative-ui" class="hash-link" aria-label="Direct link to What is imperative UI" title="Direct link to What is imperative UI" translate="no">​</a></h2>
<p>Imperative UI is when you tell the framework <em>exactly how</em> to build and update the interface step by step. You manipulate the UI directly — create controls, change their properties, insert or remove them in response to user actions.</p>
<p>For example, in an imperative style you might write:</p>
<blockquote>
<p>“Create a button, then when it's clicked, change the label's text and move it below the image.”</p>
</blockquote>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">left_column</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">visible </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">False</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">right_column</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">visible </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">True</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">right_column</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">controls</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">append</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Complete!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>Flet has championed imperative UI from the beginning, and we still believe it is a valid and straightforward approach — especially for small apps or developers without frontend experience.</p>
<p>The problem with the imperative approach, though, is that the app's state, logic, and UI all live in the same place. You constantly have to synchronize the app state and every UI element that depends on it. Add a new user to a <code>list</code>? You also have to add a corresponding <code>ft.Row</code> to display that record. As your app grows, the number of spots that must stay synchronized grows exponentially.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="what-is-declarative-ui">What is declarative UI<a href="https://flet.dev/blog/introducing-declarative-ui-in-flet#what-is-declarative-ui" class="hash-link" aria-label="Direct link to What is declarative UI" title="Direct link to What is declarative UI" translate="no">​</a></h2>
<p>The declarative approach means you describe <em>what</em> the UI should look like for a given state, not how to build or update it. Instead of manually creating, changing, or removing controls, you write a function that returns the UI structure based on current data — and the framework figures out the minimal updates needed to make it real.</p>
<p>In other words, your UI becomes a <em>pure expression of state</em>: whenever the state changes, the framework re-renders the view so it always stays consistent.</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">UI = f(state)</span><br></span></code></pre></div></div>
<p>This makes the code simpler, more predictable, and easier to reason about.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="declarative-hello-world">Declarative Hello World<a href="https://flet.dev/blog/introducing-declarative-ui-in-flet#declarative-hello-world" class="hash-link" aria-label="Direct link to Declarative Hello World" title="Direct link to Declarative Hello World" translate="no">​</a></h2>
<p>Here's a simple declarative "Hello, world" Flet app:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">App</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello, world!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">lambda</span><span class="token plain"> page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">render</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">App</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>Your app must be declarative from top to bottom, similar to how async code needs to remain async all the way. The new <code>page.render()</code> bootstrap method makes that possible.</p>
<p>For clarity, without using lambdas, the code can be rewritten as:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token decorator annotation punctuation" style="color:#393A34">@ft</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">component</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">App</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello, Flet!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Page</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">render</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">App</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic"># as before</span><br></span></code></pre></div></div>
<p>This app does nothing fancy — it simply displays the message and does not respond to user actions in any way.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="declarative-counter">Declarative Counter<a href="https://flet.dev/blog/introducing-declarative-ui-in-flet#declarative-counter" class="hash-link" aria-label="Direct link to Declarative Counter" title="Direct link to Declarative Counter" translate="no">​</a></h2>
<p>Here's a simple declarative "counter" Flet app:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator annotation punctuation" style="color:#393A34">@ft</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">component</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">App</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    count</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> set_count </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">use_state</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Row</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        controls</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token operator" style="color:#393A34">=</span><span class="token string-interpolation string" style="color:#e3116c">f"</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">count</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Button</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Add"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> on_click</span><span class="token operator" style="color:#393A34">=</span><span class="token keyword" style="color:#00009f">lambda</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> set_count</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">count </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">lambda</span><span class="token plain"> page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">render</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">App</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>You may notice a couple of new ideas here: the <code>@component</code> decorator and the <code>use_state()</code> hook — we explain both shortly.</p>
<p>The takeaway is that the <code>App</code> function is a component that returns a fresh UI (<code>Row</code>) every time the app's state changes.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="components">Components<a href="https://flet.dev/blog/introducing-declarative-ui-in-flet#components" class="hash-link" aria-label="Direct link to Components" title="Direct link to Components" translate="no">​</a></h2>
<p>In Flet's declarative approach, a component is simply a <strong>reusable function</strong> that describes a piece of UI as a function of state.</p>
<p>You can think of it as a self-contained unit that takes inputs (properties, data, event handlers) and returns Flet controls — like <code>Column</code>, <code>Text</code>, <code>Button</code>, etc. Every time its inputs or internal state change, the component rebuilds its UI, and Flet automatically updates only the changed parts.</p>
<p>Example:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token decorator annotation punctuation" style="color:#393A34">@ft</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">component</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Counter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> on_increment</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Row</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string-interpolation string" style="color:#e3116c">f"Count: </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">value</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Button</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Increment"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> on_click</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">on_increment</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>Use the <code>@component</code> decorator to mark a function as a component.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="controls-vs-components">Controls vs Components<a href="https://flet.dev/blog/introducing-declarative-ui-in-flet#controls-vs-components" class="hash-link" aria-label="Direct link to Controls vs Components" title="Direct link to Controls vs Components" translate="no">​</a></h3>
<p>A <strong>control</strong> is a UI element — the basic building block rendered on screen.
It's a concrete thing like a <code>Text</code>, <code>Button</code>, <code>Row</code>, or <code>Column</code>. Controls have properties (e.g., <code>text</code>, <code>color</code>, <code>alignment</code>) and can contain child controls.</p>
<p>Example:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Button</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Click me"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Column</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"A"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"B"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>A <strong>component</strong> is a <em>piece of logic that builds and returns controls</em>.
It's not rendered directly — instead, it describes how to create controls based on inputs or state.
Components let you group logic, reuse UI patterns, and define your own higher-level abstractions.</p>
<p>Example:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token decorator annotation punctuation" style="color:#393A34">@ft</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">component</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Greeting</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">name</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string-interpolation string" style="color:#e3116c">f"Hello, </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">name</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">!"</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>Here <code>Greeting()</code> is a component, and <code>ft.Text</code> is a control.
You can combine controls inside components, and combine components to form bigger ones — but only controls end up in the final UI tree that Flet renders.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="hooks">Hooks<a href="https://flet.dev/blog/introducing-declarative-ui-in-flet#hooks" class="hash-link" aria-label="Direct link to Hooks" title="Direct link to Hooks" translate="no">​</a></h2>
<p>Hooks are lightweight functions that let components <strong>store state</strong>, <strong>react to lifecycle events</strong>, or <strong>access shared context</strong> — all without writing classes or managing manual state objects.</p>
<p>Example:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token decorator annotation punctuation" style="color:#393A34">@ft</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">component</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Counter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    count</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> set_count </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">use_state</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Row</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        controls</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token operator" style="color:#393A34">=</span><span class="token string-interpolation string" style="color:#e3116c">f"</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">count</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Button</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Add"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> on_click</span><span class="token operator" style="color:#393A34">=</span><span class="token keyword" style="color:#00009f">lambda</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> set_count</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">count </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>Here:</p>
<ul>
<li class="">The <code>Counter()</code> component reads like a simple function.</li>
<li class=""><code>use_state(0)</code> gives it persistent state.</li>
<li class="">When <code>set_count()</code> is called, Flet re-runs the component and re-renders only what changed.</li>
</ul>
<p>That persistence is crucial: ordinary local variables are re-created on every render, so their values would disappear. Hook state survives re-renders, giving your functional components memory without resorting to globals or classes.</p>
<p>To better understand what hooks are (in an OOP analogy), imagine the <code>Counter</code> is a class, not a function. In pseudo-code the example above becomes:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Counter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Component</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    count</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> state</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">build</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> Row</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>Here, <code>count</code> is a field that holds the current counter state.</p>
<p>Hooks are a smart way to add state and behavior to functional, stateless-looking components. The idea is not unique to Flet; we borrowed it from React.</p>
<p>Flet offers the following built-in hooks:</p>
<ul>
<li class=""><code>use_state</code> - Store local state across rebuilds.</li>
<li class=""><code>use_effect</code> - Run side effects when something changes.</li>
<li class=""><code>use_context</code> - Access shared data or services.</li>
<li class=""><code>use_memo</code> - Memoize computed values.</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="observable">Observable<a href="https://flet.dev/blog/introducing-declarative-ui-in-flet#observable" class="hash-link" aria-label="Direct link to Observable" title="Direct link to Observable" translate="no">​</a></h2>
<p>Observables make the declarative UI approachable for newcomers compared to a purely React-style model. You can find observables in frameworks such as SolidJS, SwiftUI, and Jetpack Compose.</p>
<p>An observable is a reactive data holder that keeps your UI in sync automatically — whenever its value changes, the corresponding parts of the UI update instantly and efficiently.</p>
<p>There are two ways to make a class observable:</p>
<p>Inherit from <code>ft.Observable</code>:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token decorator annotation punctuation" style="color:#393A34">@dataclass</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">CounterState</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Observable</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    count</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">int</span><br></span></code></pre></div></div>
<p>Apply <code>ft.observable</code> decorator:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token decorator annotation punctuation" style="color:#393A34">@dataclass</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator annotation punctuation" style="color:#393A34">@ft</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">observable</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">CounterState</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    count</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">int</span><br></span></code></pre></div></div>
<p>Observables fit nicely into Flet's declarative approach:</p>
<ul>
<li class="">A component that accepts an observable parameter automatically re-renders when that observable updates.</li>
<li class=""><code>use_state</code> and <code>use_context</code> hooks that reference observables trigger a re-render when the observable changes.</li>
</ul>
<p>Example:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> asyncio</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> dataclasses </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> dataclass</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator annotation punctuation" style="color:#393A34">@dataclass</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator annotation punctuation" style="color:#393A34">@ft</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">observable</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">AppState</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    counter</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">float</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">start_counter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">counter </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> _ </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">range</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">counter </span><span class="token operator" style="color:#393A34">+=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> asyncio</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">sleep</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0.5</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator annotation punctuation" style="color:#393A34">@ft</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">component</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">App</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    state</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> _ </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">use_state</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">AppState</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">counter</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ProgressBar</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">state</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">counter</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Button</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Run!"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> on_click</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">state</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">start_counter</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">lambda</span><span class="token plain"> page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">render</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">App</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>Here, <code>AppState</code> is observable state, and whenever its <code>counter</code> property updates, the <code>App</code> component re-renders.</p>
<p>Compared to a pure React model, an observable makes life easier by allowing mutable state, while React assumes immutable state that must be replaced entirely to trigger a re-render.</p>
<p>For better performance, multiple updates to observable properties are coalesced, resulting in fewer UI updates when control returns to the UI loop.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="examples">Examples<a href="https://flet.dev/blog/introducing-declarative-ui-in-flet#examples" class="hash-link" aria-label="Direct link to Examples" title="Direct link to Examples" translate="no">​</a></h2>
<p>Explore the <a href="https://github.com/flet-dev/flet/tree/main/sdk/python/examples/apps/declarative" target="_blank" rel="noopener noreferrer" class="">declarative examples collection</a> to see the new approach in action — from the simple <a href="https://github.com/flet-dev/flet/blob/main/sdk/python/examples/apps/declarative/counter.py" target="_blank" rel="noopener noreferrer" class="">Counter</a> and classic <a href="https://github.com/flet-dev/flet/blob/main/sdk/python/examples/apps/declarative/todo.py" target="_blank" rel="noopener noreferrer" class="">To-Do</a> to games like <a href="https://github.com/flet-dev/flet/blob/main/sdk/python/examples/apps/declarative/tic-tac-toe.py" target="_blank" rel="noopener noreferrer" class="">Tic-Tac-Toe</a>, <a href="https://github.com/flet-dev/flet/blob/main/sdk/python/examples/apps/declarative/minesweeper.py" target="_blank" rel="noopener noreferrer" class="">Minesweeper</a>, and <a href="https://github.com/flet-dev/flet/blob/main/sdk/python/examples/tutorials/solitaire_declarative/solitaire-final/main.py" target="_blank" rel="noopener noreferrer" class="">Solitaire</a>.</p>
<p>For a deeper dive, walk through the <a href="https://flet.dev/docs/cookbook/declarative-vs-imperative-crud-app/#observables-your-source-of-truth" target="_blank" rel="noopener noreferrer" class="">Declarative vs Imperative CRUD app cookbook</a>.</p>
<img src="https://flet.dev/img/blog/declarative-ui/minesweeper.png" alt="Minesweeper game built with declarative Flet components" class="screenshot-40 screenshot-rounded">
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="faq">FAQ<a href="https://flet.dev/blog/introducing-declarative-ui-in-flet#faq" class="hash-link" aria-label="Direct link to FAQ" title="Direct link to FAQ" translate="no">​</a></h2>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="do-i-need-to-rewrite-my-existing-flet-apps-in-declarative-style">Do I need to rewrite my existing Flet apps in declarative style?<a href="https://flet.dev/blog/introducing-declarative-ui-in-flet#do-i-need-to-rewrite-my-existing-flet-apps-in-declarative-style" class="hash-link" aria-label="Direct link to Do I need to rewrite my existing Flet apps in declarative style?" title="Direct link to Do I need to rewrite my existing Flet apps in declarative style?" translate="no">​</a></h3>
<p>No! Flet supports both the current imperative approach and the new declarative approach.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="where-are-the-stateview-and-controlbuilder-controls">Where are the <code>StateView</code> and <code>ControlBuilder</code> controls?<a href="https://flet.dev/blog/introducing-declarative-ui-in-flet#where-are-the-stateview-and-controlbuilder-controls" class="hash-link" aria-label="Direct link to where-are-the-stateview-and-controlbuilder-controls" title="Direct link to where-are-the-stateview-and-controlbuilder-controls" translate="no">​</a></h3>
<p>They are gone! They were in-place prototypes for the broader declarative concept. Mixing declarative and imperative styles in the same app caused issues.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="do-i-need-to-call-update-in-a-declarative-app">Do I need to call <code>update()</code> in a declarative app?<a href="https://flet.dev/blog/introducing-declarative-ui-in-flet#do-i-need-to-call-update-in-a-declarative-app" class="hash-link" aria-label="Direct link to do-i-need-to-call-update-in-a-declarative-app" title="Direct link to do-i-need-to-call-update-in-a-declarative-app" translate="no">​</a></h3>
<p>No! In a declarative app a component is the unit of update. Whenever a component's parameters or state change, it re-renders automatically.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="how-do-i-access-the-page-instance">How do I access the <code>page</code> instance?<a href="https://flet.dev/blog/introducing-declarative-ui-in-flet#how-do-i-access-the-page-instance" class="hash-link" aria-label="Direct link to how-do-i-access-the-page-instance" title="Direct link to how-do-i-access-the-page-instance" translate="no">​</a></h3>
<p>Use <code>ft.context</code>:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">web</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="how-do-i-call-a-control-method">How do I call a control method?<a href="https://flet.dev/blog/introducing-declarative-ui-in-flet#how-do-i-call-a-control-method" class="hash-link" aria-label="Direct link to How do I call a control method?" title="Direct link to How do I call a control method?" translate="no">​</a></h3>
<p>Use an <code>ft.Ref</code> to get a reference to a control:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token decorator annotation punctuation" style="color:#393A34">@dataclass</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">State</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    txt_name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ref</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">TextField</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> field</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">default_factory</span><span class="token operator" style="color:#393A34">=</span><span class="token keyword" style="color:#00009f">lambda</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ref</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator annotation punctuation" style="color:#393A34">@ft</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">component</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">App</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">state</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">TextField</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ref</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">state</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">txt_name</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="how-do-i-use-a-textfield-or-other-input-control">How do I use a <code>TextField</code> or other input control?<a href="https://flet.dev/blog/introducing-declarative-ui-in-flet#how-do-i-use-a-textfield-or-other-input-control" class="hash-link" aria-label="Direct link to how-do-i-use-a-textfield-or-other-input-control" title="Direct link to how-do-i-use-a-textfield-or-other-input-control" translate="no">​</a></h3>
<p>The recommended approach is to use "controlled" inputs, where controls keep their state in the app's state:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> dataclasses </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> dataclass</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> typing </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> cast</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator annotation punctuation" style="color:#393A34">@dataclass</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator annotation punctuation" style="color:#393A34">@ft</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">observable</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Form</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">set_name</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> value</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">name </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> value</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">submit</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Event</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Button</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        e</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">show_dialog</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">AlertDialog</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                title</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"Hello"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                content</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string-interpolation string" style="color:#e3116c">f"Hello, </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">name</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">reset</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">name </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator annotation punctuation" style="color:#393A34">@ft</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">component</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">App</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    form</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> _ </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">use_state</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Form</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">TextField</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            label</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"Your name"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            value</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">form</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">name</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            on_change</span><span class="token operator" style="color:#393A34">=</span><span class="token keyword" style="color:#00009f">lambda</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> form</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">set_name</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">control</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">value</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Row</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            cast</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token builtin">list</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Control</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">FilledButton</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Submit"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> on_click</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">form</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">submit</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">FilledTonalButton</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Reset"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> on_click</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">form</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">reset</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">lambda</span><span class="token plain"> page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">render</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">App</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>Here, the <code>value</code> of <code>TextField</code> is stored in <code>state.name</code>, and the <code>on_change</code> handler keeps it in sync.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="call-to-action">Call to action<a href="https://flet.dev/blog/introducing-declarative-ui-in-flet#call-to-action" class="hash-link" aria-label="Direct link to Call to action" title="Direct link to Call to action" translate="no">​</a></h2>
<p>Try the new Flet declarative approach in the latest <a href="https://pypi.org/project/flet/#history" target="_blank" rel="noopener noreferrer" class="">0.70.0.dev</a> releases and let us know what you think!</p>
<p>While we update the docs to cover declarative programming in more depth, we encourage you to check the <a href="https://react.dev/learn" target="_blank" rel="noopener noreferrer" class="">React introduction</a> and try the <a href="https://react.dev/learn/tutorial-tic-tac-toe" target="_blank" rel="noopener noreferrer" class="">Tic-Tac-Toe tutorial</a>. It's not Python, but the JavaScript is simple to follow.</p>
<p>We built a similar <a href="https://github.com/flet-dev/flet/blob/main/sdk/python/examples/apps/declarative/tic-tac-toe.py" target="_blank" rel="noopener noreferrer" class="">declarative Tic-Tac-Toe</a> Flet app that you can compare with its React counterpart as you work through the tutorial.</p>
<p>The next stop is the Flet 1.0 Beta release. We're almost there — new docs (you can follow their progress <a href="https://flet.dev/docs/" target="_blank" rel="noopener noreferrer" class="">here</a>), more integration tests, and plenty of polish are underway.</p>
<p>Happy Fletting!</p>]]></content>
        <author>
            <name>Feodor Fitsner</name>
            <uri>ttps://github.com/FeodorFitsner</uri>
        </author>
        <category label="news" term="news"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Introducing Flet 1.0 Alpha]]></title>
        <id>https://flet.dev/blog/introducing-flet-1-0-alpha</id>
        <link href="https://flet.dev/blog/introducing-flet-1-0-alpha"/>
        <updated>2025-06-26T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flet has been in the making for over three years, steadily gaining traction and building a vibrant user community. As more developers adopt Flet for real-world projects, one thing has become clear: people are ready to commit — but they also want to see the same commitment from us.]]></summary>
        <content type="html"><![CDATA[<p>Flet has been in the making for over three years, steadily gaining traction and building a vibrant user community. As more developers adopt Flet for real-world projects, one thing has become clear: people are ready to commit — but they also want to see the same commitment from us.</p>
<p>Releasing <strong>Flet 1.0</strong> isn’t just about a version number. It’s about signaling stability, maturity, and long-term vision. A stable API, comprehensive documentation, better testing and clearly communicated roadmap — these are the foundational pieces developers need to confidently build serious apps on Flet.</p>
<p>But <strong>Flet 1.0 isn’t just the next incremental release. It’s a complete re-architecture</strong>.</p>
<p>The first versions of Flet inherited design decisions from Pglet — a web-based framework with a focus on multi-language support. While that served as a useful starting point, Flet has since evolved into a Python-centric framework for building cross-platform apps — web, desktop, and mobile.</p>
<p>With that evolution came technical debt, architectural misfits, and increasing complexity. Rather than patch over the cracks, we made a bold decision: to rewrite Flet from the ground up. It’s always risky to rewrite, but there’s no better time than now — before 1.0 — while the user base is still manageable and we can afford to break things in the name of long-term simplicity and maintainability.</p>
<p>After nearly five months of work, <strong>today we’re releasing the Flet 1.0 Alpha — a technical preview of what’s coming.</strong></p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="whats-new">What’s new<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#whats-new" class="hash-link" aria-label="Direct link to What’s new" title="Direct link to What’s new" translate="no">​</a></h2>
<p>Flet 1.0 introduces major changes that simplify how you build, run, and scale apps. Some are improvements, some are breaking — all are focused on giving you a faster, more flexible developer experience.</p>
<ul>
<li class=""><strong>Declarative approach to building Flet apps</strong> - alongside the traditional imperative style.</li>
<li class=""><strong>Auto-update</strong> - automatic page updates after event handler completion.</li>
<li class=""><strong>Services</strong> - persistent, non-UI components that live across UI rebuilds and navigation. Existing controls such as <code>Audio</code>, <code>FilePicker</code>, <code>Clipboard</code> were re-written as services.</li>
<li class=""><strong>Complete WASM (WebAssembly) support for web apps</strong> - faster download and performance on modern browsers.</li>
<li class=""><strong>Offline (no-CDN) mode for web apps</strong> - Flutter resources and Pyodide are bundled with the app.</li>
<li class=""><strong>Embedding Flet apps into existing web page</strong> - render Flet app into an HTML element on any web page.</li>
<li class=""><strong>Enhanced Extensions API</strong> - to export services along with controls, with a room for future customizations like splash and loading screens.</li>
</ul>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="declarative-approach">Declarative approach<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#declarative-approach" class="hash-link" aria-label="Direct link to Declarative approach" title="Direct link to Declarative approach" translate="no">​</a></h3>
<p>Flet 1.0 introduces a <strong>declarative/reactive approach</strong> to building UIs in Flet. Developers can now mix <strong>imperative</strong> and <strong>declarative</strong> patterns in the same app, enabling more flexible and functional UI code.</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="basic-declarative-flet-app-example">Basic declarative Flet app example<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#basic-declarative-flet-app-example" class="hash-link" aria-label="Direct link to Basic declarative Flet app example" title="Direct link to Basic declarative Flet app example" translate="no">​</a></h4>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> dataclasses </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> dataclass</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator annotation punctuation" style="color:#393A34">@dataclass</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">AppState</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    count</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">int</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">increment</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">count </span><span class="token operator" style="color:#393A34">+=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Page</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    state </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> AppState</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">count</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">floating_action_button </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">FloatingActionButton</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        icon</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Icons</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ADD</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> on_click</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">state</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">increment</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ControlBuilder</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            state</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">lambda</span><span class="token plain"> state</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">SafeArea</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Container</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token operator" style="color:#393A34">=</span><span class="token string-interpolation string" style="color:#e3116c">f"</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">state</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">count</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> size</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">50</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    alignment</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Alignment</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">center</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                expand</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            expand</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>More declarative examples:</p>
<ul>
<li class=""><a href="https://github.com/flet-dev/examples/blob/v1/python/apps/declarative/edit-form.py" target="_blank" rel="noopener noreferrer" class="">Edit form</a></li>
<li class=""><a href="https://github.com/flet-dev/examples/blob/v1/python/apps/declarative/progress-with-yield.py" target="_blank" rel="noopener noreferrer" class="">Progress bar with yield</a></li>
<li class="">🚀 <a href="https://github.com/flet-dev/examples/blob/v1/python/apps/todo/todo-reactive.py" target="_blank" rel="noopener noreferrer" class="">Reactive ToDo app</a></li>
</ul>
<p>🚧 Documentation is in progress 🚧</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="auto-update">Auto-update<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#auto-update" class="hash-link" aria-label="Direct link to Auto-update" title="Direct link to Auto-update" translate="no">​</a></h3>
<p><code>Control.update()</code> is now automatically called once its event handler method is finished.
Most of Flet apps will now work without explicit <code>update()</code> calls.</p>
<p>Use <code>yield</code> inside long-running event handlers to refresh UI, for example:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">button_click</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  progress</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">value </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Something started"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">yield</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> asyncio</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">sleep</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  progress</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">value </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Something finished"</span><br></span></code></pre></div></div>
<p>🚧 Documentation is in progress 🚧</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="services">Services<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#services" class="hash-link" aria-label="Direct link to Services" title="Direct link to Services" translate="no">​</a></h3>
<p>"Service" is a persistent, non-visual control that can "survive" page updates and navigation transitions.</p>
<p>Some of the existing controls were re-implemented as services (breaking change):</p>
<ul>
<li class=""><code>Audio</code> (<a href="https://pypi.org/project/flet-audio/" target="_blank" rel="noopener noreferrer" class="">extension</a>)</li>
<li class=""><code>AudioRecorder</code> (<a href="https://pypi.org/project/flet-audio-recorder/" target="_blank" rel="noopener noreferrer" class="">extension</a>)</li>
<li class=""><code>FilePicker</code></li>
<li class=""><code>Flashlight</code> (<a href="https://pypi.org/project/flet-flashlight/" target="_blank" rel="noopener noreferrer" class="">extension</a>)</li>
<li class=""><code>Geolocator</code> (<a href="https://pypi.org/project/flet-geolocator/" target="_blank" rel="noopener noreferrer" class="">extension</a>)</li>
<li class=""><code>HapticFeedback</code></li>
<li class=""><code>InterstitialAd</code> (<a href="https://pypi.org/project/flet-ads/" target="_blank" rel="noopener noreferrer" class="">extension</a>)</li>
<li class=""><code>PermissionHandler</code> (<a href="https://pypi.org/project/flet-permission-handler/" target="_blank" rel="noopener noreferrer" class="">extension</a>)</li>
<li class=""><code>SemanticsService</code></li>
<li class=""><code>ShakeDetector</code></li>
</ul>
<p>Service instances must be added to <code>page.services</code> list to work.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="webassembly-support">WebAssembly support<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#webassembly-support" class="hash-link" aria-label="Direct link to WebAssembly support" title="Direct link to WebAssembly support" translate="no">​</a></h3>
<p>Flet 1.0 web apps use WebAssembly (WASM) by default on <a href="https://docs.flutter.dev/platform-integration/web/wasm#learn-more-about-browser-compatibility" target="_blank" rel="noopener noreferrer" class="">selected browsers</a>.</p>
<p>Built-in Flet web client and Flet apps built with <code>flet build web</code> are now include both Dart2JS (with CanvasKit as a renderer) and WebAssembly (with SKWASM renderer) targets.</p>
<p>🚧 Documentation is in progress 🚧</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="offline-mode-for-web-apps">Offline mode for web apps<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#offline-mode-for-web-apps" class="hash-link" aria-label="Direct link to Offline mode for web apps" title="Direct link to Offline mode for web apps" translate="no">​</a></h3>
<p>Flet 1.0 has "no-CDN" mode which allows bundling the following resources along with your app instead of loading them from external CDNs:</p>
<ul>
<li class="">CanvasKit</li>
<li class="">SkWASM</li>
<li class="">Pyodide</li>
<li class="">Fonts</li>
</ul>
<p>To enable no-CDN during runtime either add <code>no_cdn=True</code> to <code>ft.run()</code> (it's a new <code>ft.run()</code>) call:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> no_cdn</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>or set <code>FLET_WEB_NO_CDN</code> environment variable to <code>1</code>, <code>true</code> or <code>yes</code>.</p>
<p>To enable no-CDN for <code>flet build</code> add <code>--no-cdn</code> argument.</p>
<p>🚧 Documentation is in progress 🚧</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="embedding-flet-web-apps">Embedding Flet web apps<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#embedding-flet-web-apps" class="hash-link" aria-label="Direct link to Embedding Flet web apps" title="Direct link to Embedding Flet web apps" translate="no">​</a></h3>
<p>You can now embed a Flet web app into any HTML element within an existing web page.</p>
<p>It's also possible to render multiple views of the same app in different HTML elements.</p>
<p>🚧 Documentation is in progress 🚧</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="enhanced-extensions-api">Enhanced Extensions API<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#enhanced-extensions-api" class="hash-link" aria-label="Direct link to Enhanced Extensions API" title="Direct link to Enhanced Extensions API" translate="no">​</a></h3>
<p>The new extensions API allows exporting from your Flutter package of both control and service widgets. Technically, an extension is a class now rather than a method which will allow us to add more hooks into it like custom spash and loading screens.</p>
<p>For example, <code>flet-ads</code> extension before has just one <code>createControl</code> method:</p>
<div class="language-dart codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_OeMC">create_control.dart</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-dart codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">import 'package:flet/flet.dart';</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">import 'package:google_mobile_ads/google_mobile_ads.dart';</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">import 'banner.dart';</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">import 'interstitial.dart';</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">CreateControlFactory createControl = (CreateControlArgs args) {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  switch (args.control.type) {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    case "banner_ad":</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      return BannerAdControl(</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          parent: args.parent, control: args.control, backend: args.backend);</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    case "interstitial_ad":</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      return InterstitialAdControl(</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          parent: args.parent, control: args.control, backend: args.backend);</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    default:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      return null;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">};</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">void ensureInitialized() {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  if (isMobilePlatform()) {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    MobileAds.instance.initialize();</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span></code></pre></div></div>
<p>and for Flet v1 it has two methods <code>createWidget</code> and <code>createService</code>:</p>
<div class="language-dart codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_OeMC">extension.dart</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-dart codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">import 'package:flet/flet.dart';</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">import 'package:flutter/cupertino.dart';</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">import 'package:google_mobile_ads/google_mobile_ads.dart';</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">import 'banner.dart';</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">import 'interstitial.dart';</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">class Extension extends FletExtension {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  @override</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  void ensureInitialized() {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    if (isMobilePlatform()) {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      MobileAds.instance.initialize();</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  @override</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  FletService? createService(Control control) {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    switch (control.type) {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      case "InterstitialAd":</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        return InterstitialAdService(control: control);</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      default:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        return null;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  @override</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  Widget? createWidget(Key? key, Control control) {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    switch (control.type) {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      case "BannerAd":</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        return BannerAdControl(control: control);</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      default:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        return null;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span></code></pre></div></div>
<p>This change is breaking.</p>
<p>🚧 Documentation is in progress 🚧</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="other-changes-and-improvements">Other changes and improvements<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#other-changes-and-improvements" class="hash-link" aria-label="Direct link to Other changes and improvements" title="Direct link to Other changes and improvements" translate="no">​</a></h3>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="ftrun-with-before_main"><code>ft.run</code> with <code>before_main</code><a href="https://flet.dev/blog/introducing-flet-1-0-alpha#ftrun-with-before_main" class="hash-link" aria-label="Direct link to ftrun-with-before_main" title="Direct link to ftrun-with-before_main" translate="no">​</a></h3>
<p>A new <code>before_main</code> arg added to <code>ft.run()</code> (replaces <code>ft.run()</code>). <code>before_main</code> is a hook that allows to reliable configure page-level event handlers before Flutter client starts sending events. <code>before_main</code> is a function that accepts one parameter: <code>page: ft.Page</code></p>
<p>Example usage:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">config</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Page</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">on_resize </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">lambda</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Page resized!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Page</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> before_main</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">config</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="storage-paths">Storage paths<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#storage-paths" class="hash-link" aria-label="Direct link to Storage paths" title="Direct link to Storage paths" translate="no">​</a></h4>
<p>There is a new <code>page.storage_paths</code> multi-platform API based on <a href="https://pub.dev/packages/path_provider" target="_blank" rel="noopener noreferrer" class="">path_provider</a> for finding commonly used locations on the filesystem:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">get_application_cache_directory_async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">get_application_documents_directory_async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">get_application_support_directory_async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">get_downloads_directory_async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> Optional</span><span class="token punctuation" style="color:#393A34">[</span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">get_external_cache_directories_async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> Optional</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">List</span><span class="token punctuation" style="color:#393A34">[</span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">get_external_storage_directories_async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> Optional</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">List</span><span class="token punctuation" style="color:#393A34">[</span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">get_library_directory_async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">get_external_cache_directory_async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> Optional</span><span class="token punctuation" style="color:#393A34">[</span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">get_temporary_directory_async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">get_console_log_filename_async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token builtin">str</span><br></span></code></pre></div></div>
<p>🚧 Documentation is in progress 🚧</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="event-handlers-without-e">Event handlers without <code>e</code><a href="https://flet.dev/blog/introducing-flet-1-0-alpha#event-handlers-without-e" class="hash-link" aria-label="Direct link to event-handlers-without-e" title="Direct link to event-handlers-without-e" translate="no">​</a></h4>
<p>Event handlers can now omit <code>e</code> parameter, for example both of these work:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">button_1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">on_click </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">lambda</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Clicked!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">button_2</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">on_click </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">lambda</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Clicked!"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>or</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">increment</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Increment clicked"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">inc_btn</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">on_click </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> increment</span><br></span></code></pre></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="controlbefore_evente-hook"><code>Control.before_event(e)</code> hook<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#controlbefore_evente-hook" class="hash-link" aria-label="Direct link to controlbefore_evente-hook" title="Direct link to controlbefore_evente-hook" translate="no">​</a></h4>
<p>The method is called before calling any event handler.</p>
<p>It receives an instance of <code>ControlEvent</code> as parameter and should return either <code>True</code> or <code>False</code>. Returning <code>False</code> cancels event handler. Example implementation in <code>Page</code> class:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">before_event</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ControlEvent</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token builtin">isinstance</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> RouteChangeEvent</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">route </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">route</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">False</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">query</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token builtin">super</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">before_event</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="ftcontextpage-works-everywhere"><code>ft.context.page</code> works everywhere<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#ftcontextpage-works-everywhere" class="hash-link" aria-label="Direct link to ftcontextpage-works-everywhere" title="Direct link to ftcontextpage-works-everywhere" translate="no">​</a></h4>
<p>It's now possible to get a reference to a current <code>Page</code> instance in any part of Flet program.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="the-new-architecture">The new Architecture<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#the-new-architecture" class="hash-link" aria-label="Direct link to The new Architecture" title="Direct link to The new Architecture" translate="no">​</a></h2>
<p>Flet 1.0 is not just a feature release — it's a ground-up rewrite designed to address technical debt, improve maintainability, and unlock long-term performance and flexibility. Here are some of the most impactful architectural changes:</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="simplified-python-control-implementation">Simplified Python control implementation<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#simplified-python-control-implementation" class="hash-link" aria-label="Direct link to Simplified Python control implementation" title="Direct link to Simplified Python control implementation" translate="no">​</a></h3>
<ul>
<li class="">
<p>Controls are now implemented as Python <strong>dataclasses</strong>, bringing:</p>
<ul>
<li class="">Automatic constructor generation</li>
<li class="">Native support for default values, type annotations, and field validation</li>
<li class="">No more manual conversions to/from <code>str</code> or <code>JSON</code></li>
<li class="">Seamless support for <strong>complex property types</strong> (nested dataclasses, enums, etc.)</li>
</ul>
</li>
<li class="">
<p>This significantly reduces boilerplate and makes adding new controls trivial — often zero-maintenance.</p>
</li>
</ul>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="strong-typing-and-ide-support">Strong typing and IDE support<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#strong-typing-and-ide-support" class="hash-link" aria-label="Direct link to Strong typing and IDE support" title="Direct link to Strong typing and IDE support" translate="no">​</a></h3>
<ul>
<li class="">Event handlers are now <strong>strongly typed</strong>, improving both runtime safety and developer ergonomics.</li>
<li class="">All controls include <strong>docstrings</strong>, enabling rich auto-generated API documentation with <strong>Docusaurus</strong>.</li>
</ul>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="smarter-ui-diffing">Smarter UI diffing<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#smarter-ui-diffing" class="hash-link" aria-label="Direct link to Smarter UI diffing" title="Direct link to Smarter UI diffing" translate="no">​</a></h3>
<ul>
<li class="">A new <strong>diffing algorithm</strong> powers efficient updates to the UI tree.</li>
<li class="">It’s optimized for both <strong>imperative</strong> and <strong>declarative</strong> Flet programming styles.</li>
<li class="">This results in faster rebuilds and fewer unnecessary redraws.</li>
</ul>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="dart-runtime-modernization">Dart runtime modernization<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#dart-runtime-modernization" class="hash-link" aria-label="Direct link to Dart runtime modernization" title="Direct link to Dart runtime modernization" translate="no">​</a></h3>
<ul>
<li class="">Replaced the old Redux-based state management with <strong>InheritedWidget</strong> + <strong>Provider</strong>.</li>
<li class="">The internal control hierarchy on the Dart side now mirrors the Python control tree, enabling <strong>more efficient traversal and updates</strong>.</li>
</ul>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="binary-protocol-for-performance">Binary protocol for performance<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#binary-protocol-for-performance" class="hash-link" aria-label="Direct link to Binary protocol for performance" title="Direct link to Binary protocol for performance" translate="no">​</a></h3>
<ul>
<li class="">
<p>A new <strong>binary serialization protocol</strong> (MessagePack) replaces the JSON-based message format:</p>
<ul>
<li class="">Significantly reduces traffic size</li>
<li class="">No more base64 encoding for transferring binary data (e.g., images, files)</li>
</ul>
</li>
<li class="">
<p>Control property names in Dart now <strong>exactly match their Python counterparts</strong>, making it easier to debug and extend across both runtimes.</p>
</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="breaking-changes">Breaking changes<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#breaking-changes" class="hash-link" aria-label="Direct link to Breaking changes" title="Direct link to Breaking changes" translate="no">​</a></h2>
<p>Flet 1.0 is a major release and includes breaking changes — for good reason!</p>
<p>The Flet team maintains a list of known breaking changes in <a href="https://github.com/flet-dev/flet/issues/5238" target="_blank" rel="noopener noreferrer" class="">this issue</a>.</p>
<p>If you discover something else that’s broken or incorrect, please submit a new issue or discussion. Once confirmed, we’ll update the list.</p>
<p>Below is a summary of the most significant and impactful breaking changes:</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="single-threaded-async-ui-model">Single-threaded async UI model<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#single-threaded-async-ui-model" class="hash-link" aria-label="Direct link to Single-threaded async UI model" title="Direct link to Single-threaded async UI model" translate="no">​</a></h3>
<p>Flet 1.0 adopts a single-threaded async UI model, similar to JavaScript or Flutter. This design makes concurrency more predictable and better suited for the browser and mobile platforms.</p>
<ul>
<li class="">Blocking calls like <code>time.sleep()</code> will freeze the UI. Instead of <code>time.sleep()</code> use <code>async def</code> event handlers and using <code>await asyncio.sleep()</code> for delays.</li>
<li class="">Switch to async APIs whenever possible.</li>
<li class="">For CPU-bound tasks, offload them to threads using <code>asyncio.to_thread(...)</code>.</li>
</ul>
<p>🚧 Example with CPU-bound method updating progress bar 🚧</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="async-control-methods">Async control methods<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#async-control-methods" class="hash-link" aria-label="Direct link to Async control methods" title="Direct link to Async control methods" translate="no">​</a></h3>
<p>All controls' get- and set- methods are async now.</p>
<p>Methods that do not return any results have fire-and-forget sync wrappers.</p>
<p>🚧 Documentation is in progress 🚧</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="ftrun-replaces-ftrun"><code>ft.run()</code> replaces <code>ft.run()</code><a href="https://flet.dev/blog/introducing-flet-1-0-alpha#ftrun-replaces-ftrun" class="hash-link" aria-label="Direct link to ftrun-replaces-ftrun" title="Direct link to ftrun-replaces-ftrun" translate="no">​</a></h3>
<p><code>target</code> argument renamed to <code>main</code> and the rest of method arguments stays the same. A new <code>before_main</code> argument added (see above).</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="page-split"><code>Page</code> split<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#page-split" class="hash-link" aria-label="Direct link to page-split" title="Direct link to page-split" translate="no">​</a></h3>
<p><code>Page</code> split into <code>Page</code> and <code>PageView</code>.</p>
<p>To support Flet embedding with multi-views.</p>
<p>It's not a breaking-change per-se if you just continue to use <code>page</code> instance methods or properties.</p>
<p>🚧 Documentation is in progress 🚧</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="dialogs">Dialogs<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#dialogs" class="hash-link" aria-label="Direct link to Dialogs" title="Direct link to Dialogs" translate="no">​</a></h3>
<p>To display a dialog, banner, snack bar, drawer, or any similar popup control, use <code>page.show_dialog(dialog_control)</code> instead of <code>page.open()</code>.</p>
<p>To close the topmost popup, use <code>page.pop_dialog()</code>.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="drawers">Drawers<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#drawers" class="hash-link" aria-label="Direct link to Drawers" title="Direct link to Drawers" translate="no">​</a></h3>
<p><code>page.drawer</code> and <code>page.end_drawer</code> were removed.</p>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_BuS1"><p>We might re-introduce this in the future, to fix displaying of the top menu icon button as in this <a href="https://api.flutter.dev/flutter/material/Scaffold/endDrawer.html" target="_blank" rel="noopener noreferrer" class="">example</a>.</p></div></div>
<p>Use <code>NavigationDrawer.position</code> property and then <code>page.show_dialog()</code> to display drawer instead of <code>page.drawer</code> and <code>page.end_drawer</code>.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="filepicker">FilePicker<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#filepicker" class="hash-link" aria-label="Direct link to FilePicker" title="Direct link to FilePicker" translate="no">​</a></h3>
<p>FilePicker is now a service and must be added to <code>page.services</code> list to work.</p>
<p>API re-worked to provide async methods immediatly returning dialog results without using "result" event handlers.</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">files</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">list</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">FilePickerFile</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> file_picker</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">pick_files_async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">allow_multiple</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">file_name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> file_picker</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">save_file_async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">dir_name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> file_picker</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">get_directory_path_async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>Full examples:</p>
<ul>
<li class=""><a href="https://github.com/flet-dev/examples/blob/v1/python/controls/utility/file-picker/file-picker-all-modes.py" target="_blank" rel="noopener noreferrer" class="">All dialogs</a></li>
<li class=""><a href="https://github.com/flet-dev/examples/blob/v1/python/controls/utility/file-picker/file-picker-upload-progress.py" target="_blank" rel="noopener noreferrer" class="">Upload</a></li>
</ul>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="clipboard">Clipboard<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#clipboard" class="hash-link" aria-label="Direct link to Clipboard" title="Direct link to Clipboard" translate="no">​</a></h3>
<p>Instead of <code>page.set_clipboard()</code> use <code>page.clipboard.set_async()</code>.</p>
<p>Instead of <code>page.get_clipboard()</code> use <code>page.clipboard.get_async()</code>.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="client-storage">Client storage<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#client-storage" class="hash-link" aria-label="Direct link to Client storage" title="Direct link to Client storage" translate="no">​</a></h3>
<p>"Client storage" is now "Shared Preferences".</p>
<p><code>page.client_storage</code> property renamed to <code>page.shared_preferences</code>.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="scrollables">Scrollables<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#scrollables" class="hash-link" aria-label="Direct link to Scrollables" title="Direct link to Scrollables" translate="no">​</a></h3>
<p>In scrollable controls <code>on_scroll_interval</code> property renamed to <code>scroll_interval</code>.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="buttons">Buttons<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#buttons" class="hash-link" aria-label="Direct link to Buttons" title="Direct link to Buttons" translate="no">​</a></h3>
<p>All buttons: no <code>text</code> property, use <code>content</code> instead.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="charts">Charts<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#charts" class="hash-link" aria-label="Direct link to Charts" title="Direct link to Charts" translate="no">​</a></h3>
<p>Chart controls have been moved to a separate package <a href="https://pypi.org/project/flet-charts/" target="_blank" rel="noopener noreferrer" class="">flet-charts</a>.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="control-id-is-integer">Control ID is integer<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#control-id-is-integer" class="hash-link" aria-label="Direct link to Control ID is integer" title="Direct link to Control ID is integer" translate="no">​</a></h3>
<p><code>e.target</code> is a number now, not a string.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="trying-flet-10-alpha">Trying Flet 1.0 Alpha<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#trying-flet-10-alpha" class="hash-link" aria-label="Direct link to Trying Flet 1.0 Alpha" title="Direct link to Trying Flet 1.0 Alpha" translate="no">​</a></h2>
<p>We are releasing Flet 1.0 Alpha as <a href="https://pypi.org/project/flet/#history" target="_blank" rel="noopener noreferrer" class="">0.70.0.devXXXX</a>.</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_BuS1"><p>Going forward Flet 1.0 will be called <code>v1</code> and Flet 0.x will be called <code>v0</code>.</p><p><code>main</code> branch of Flet repository will have Flet 1.0 and <code>v0</code> branch will have Flet 0.x.</p></div></div>
<div class="theme-admonition theme-admonition-caution admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>caution</div><div class="admonitionContent_BuS1"><p>Make sure you are installing Flet pre-release to a new virtual environment.</p></div></div>
<p>To install Flet v1 Alpha with pip:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pip install --pre 'flet[all]&gt;=0.70.0.dev0'</span><br></span></code></pre></div></div>
<p>or install with uv:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">uv add 'flet[all]&gt;=0.70.0.dev0' --prerelease=allow</span><br></span></code></pre></div></div>
<p>or add <code>flet &gt;=0.70.0.dev0</code> to dependencies of your Python project.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="flet-build"><code>flet build</code><a href="https://flet.dev/blog/introducing-flet-1-0-alpha#flet-build" class="hash-link" aria-label="Direct link to flet-build" title="Direct link to flet-build" translate="no">​</a></h3>
<p>To make <code>flet build</code> work with Flet 1.0 Alpha specify exact version of <code>flet</code> and all extension packages in <code>dependencies</code> section of your <code>pyproject.toml</code>:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">dependencies=[</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  "flet &gt;=0.70.0.dev0",</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  "flet-audio &gt;=0.2.0.dev0",</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  "flet-video &gt;=0.2.0.dev0",</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  ...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">]</span><br></span></code></pre></div></div>
<p>Extensions for Flet v1 will have version <code>0.2.x</code> and above and Flet v0 extensions will have version <code>0.1.x</code>.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="roadmap-to-flet-10">Roadmap to Flet 1.0<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#roadmap-to-flet-10" class="hash-link" aria-label="Direct link to Roadmap to Flet 1.0" title="Direct link to Roadmap to Flet 1.0" translate="no">​</a></h2>
<ul>
<li class="">Flet 0.70 aka "<strong>Flet 1.0 Alpha</strong>" - this release. Generated docs are not yet included. We may release a few Flet 0.71, 0.72, 0.73, etc. to fix things.</li>
<li class="">Flet 0.80 aka "<strong>Flet 1.0 Beta</strong>" - docs generated from sources are ready. All extensions are working and documented. Integration tests are available.</li>
<li class="">Flet 0.90 aka "<strong>Flet 1.0 RC</strong>" - website landing page is updated, API complete and frozen.</li>
<li class="">Flet 1.0 aka "<strong>Flet 1.0 RTM</strong>" - final release! <!-- -->🎉</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="conclusion">Conclusion<a href="https://flet.dev/blog/introducing-flet-1-0-alpha#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>Flet 1.0 Alpha marks the beginning of a new chapter for the framework — one focused on performance, maintainability, and developer experience. It introduces a streamlined architecture, a powerful declarative programming model, and a reimagined extension system — all while laying the groundwork for a stable and scalable 1.0 release.</p>
<p>This is a technical preview, and while it's not production-ready yet, we invite you to try it out, share your feedback, and help us shape the future of Flet.</p>
<p>We’re incredibly excited about what’s coming next — and we’re just getting started.</p>]]></content>
        <author>
            <name>Feodor Fitsner</name>
            <uri>ttps://github.com/FeodorFitsner</uri>
        </author>
        <category label="news" term="news"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tap into native Android and iOS APIs with Pyjnius and Pyobjus]]></title>
        <id>https://flet.dev/blog/tap-into-native-android-and-ios-apis-with-Pyjnius-and-pyobjus</id>
        <link href="https://flet.dev/blog/tap-into-native-android-and-ios-apis-with-Pyjnius-and-pyobjus"/>
        <updated>2025-02-23T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[When building mobile apps with Flet, you may need to interact directly with platform-specific APIs. Whether it’s accessing system information, managing Bluetooth devices, or working with user preferences, Pyjnius and Pyobjus by Kivy provide a seamless way to bridge Python with Java (for Android) and Objective-C (for iOS).]]></summary>
        <content type="html"><![CDATA[<p>When building mobile apps with Flet, you may need to interact directly with platform-specific APIs. Whether it’s accessing system information, managing Bluetooth devices, or working with user preferences, <strong>Pyjnius</strong> and <strong>Pyobjus</strong> by Kivy provide a seamless way to bridge Python with Java (for Android) and Objective-C (for iOS).</p>
<p>You can now integrate both Pyjnius and Pyobjus into your Flet apps! 🚀</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="pyjnius-for-android">Pyjnius for Android<a href="https://flet.dev/blog/tap-into-native-android-and-ios-apis-with-Pyjnius-and-pyobjus#pyjnius-for-android" class="hash-link" aria-label="Direct link to Pyjnius for Android" title="Direct link to Pyjnius for Android" translate="no">​</a></h2>
<p>Pyjnius is a Python library for accessing Java classes using the <strong>Java Native Interface</strong> (JNI).</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="adding-to-a-project">Adding to a project<a href="https://flet.dev/blog/tap-into-native-android-and-ios-apis-with-Pyjnius-and-pyobjus#adding-to-a-project" class="hash-link" aria-label="Direct link to Adding to a project" title="Direct link to Adding to a project" translate="no">​</a></h3>
<p>Add <code>pyjnius</code> dependency for Android builds only (other settings in <code>pyproject.toml</code> were omitted for brevity):</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[project]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">name = "pyjnius_demo"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">version = "0.1.0"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">dependencies = [</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  "flet==0.27.1"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.android]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">dependencies = [</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  "pyjnius"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">]</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="usage-examples">Usage examples<a href="https://flet.dev/blog/tap-into-native-android-and-ios-apis-with-Pyjnius-and-pyobjus#usage-examples" class="hash-link" aria-label="Direct link to Usage examples" title="Direct link to Usage examples" translate="no">​</a></h3>
<p>Here are some example of how Pyjnius can be used in your Flet Android app.</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="getting-android-os-details">Getting Android OS details<a href="https://flet.dev/blog/tap-into-native-android-and-ios-apis-with-Pyjnius-and-pyobjus#getting-android-os-details" class="hash-link" aria-label="Direct link to Getting Android OS details" title="Direct link to Getting Android OS details" translate="no">​</a></h4>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> jnius </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> autoclass</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Get Build and Build.VERSION classes</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Build </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> autoclass</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'android.os.Build'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Version </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> autoclass</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'android.os.Build$VERSION'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Get OS details</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">device_model </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Build</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">MODEL</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">manufacturer </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Build</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">MANUFACTURER</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">brand </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Build</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">BRAND</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">hardware </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Build</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">HARDWARE</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">product </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Build</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">PRODUCT</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">device </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Build</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">DEVICE</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">os_version </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Version</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">RELEASE</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">sdk_version </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Version</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">SDK_INT</span><br></span></code></pre></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="listing-bluetooth-devices">Listing Bluetooth devices<a href="https://flet.dev/blog/tap-into-native-android-and-ios-apis-with-Pyjnius-and-pyobjus#listing-bluetooth-devices" class="hash-link" aria-label="Direct link to Listing Bluetooth devices" title="Direct link to Listing Bluetooth devices" translate="no">​</a></h4>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> jnius </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> autoclass</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Get BluetoothAdapter instance</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">BluetoothAdapter </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> autoclass</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'android.bluetooth.BluetoothAdapter'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">bluetooth_adapter </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> BluetoothAdapter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">getDefaultAdapter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> bluetooth_adapter </span><span class="token keyword" style="color:#00009f">is</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">None</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Bluetooth not supported on this device"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">else</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">not</span><span class="token plain"> bluetooth_adapter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">isEnabled</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Bluetooth is disabled. Please enable it."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">else</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Bluetooth is enabled."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic"># Get paired devices</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        paired_devices </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> bluetooth_adapter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">getBondedDevices</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> device </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> paired_devices</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">toArray</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string-interpolation string" style="color:#e3116c">f"Device Name: </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">device</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">getName</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">(</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">)</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">, MAC Address: </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">device</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">getAddress</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">(</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">)</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="accessing-the-activity">Accessing the Activity<a href="https://flet.dev/blog/tap-into-native-android-and-ios-apis-with-Pyjnius-and-pyobjus#accessing-the-activity" class="hash-link" aria-label="Direct link to Accessing the Activity" title="Direct link to Accessing the Activity" translate="no">​</a></h3>
<p>App main activity instance can be retrieved with the following code:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> os</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> jnius </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> autoclass</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">activity_host_class </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">getenv</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"MAIN_ACTIVITY_HOST_CLASS_NAME"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">assert</span><span class="token plain"> activity_host_class</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">activity_host </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> autoclass</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">activity_host_class</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">activity </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> activity_host</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">mActivity</span><br></span></code></pre></div></div>
<p>Heck, you can basically call any Android API using Pyjnius - endless posibilities!</p>
<p>Check complete <a href="https://github.com/flet-dev/python-package-tests/tree/main/pyjnius" target="_blank" rel="noopener noreferrer" class="">Flet Pyjnius example</a>.</p>
<p>For more Pyjnius examples and API refer to the <a href="https://pyjnius.readthedocs.io/en/latest/quickstart.html" target="_blank" rel="noopener noreferrer" class="">Pyjnius Documentation</a>.</p>
<p>...or just use ChatGPT (or your favorite LLM) to get more ideas and solutions! 😅</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="pyobjus-for-ios">Pyobjus for iOS<a href="https://flet.dev/blog/tap-into-native-android-and-ios-apis-with-Pyjnius-and-pyobjus#pyobjus-for-ios" class="hash-link" aria-label="Direct link to Pyobjus for iOS" title="Direct link to Pyobjus for iOS" translate="no">​</a></h2>
<p>Pyobjus is a library for accessing Objective-C classes as Python classes using Objective-C runtime reflection.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="adding-to-a-project-1">Adding to a project<a href="https://flet.dev/blog/tap-into-native-android-and-ios-apis-with-Pyjnius-and-pyobjus#adding-to-a-project-1" class="hash-link" aria-label="Direct link to Adding to a project" title="Direct link to Adding to a project" translate="no">​</a></h3>
<p>Add <code>pyobjus</code> dependency for iOS builds only (other settings in <code>pyproject.toml</code> were omitted for brevity):</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[project]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">name = "Pyjnius"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">version = "0.1.0"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">dependencies = [</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  "flet==0.27.1"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.ios]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">dependencies = [</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  "pyobjus"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">]</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="usage-examples-1">Usage examples<a href="https://flet.dev/blog/tap-into-native-android-and-ios-apis-with-Pyjnius-and-pyobjus#usage-examples-1" class="hash-link" aria-label="Direct link to Usage examples" title="Direct link to Usage examples" translate="no">​</a></h3>
<h4 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="the-simplest-example">The simplest example<a href="https://flet.dev/blog/tap-into-native-android-and-ios-apis-with-Pyjnius-and-pyobjus#the-simplest-example" class="hash-link" aria-label="Direct link to The simplest example" title="Direct link to The simplest example" translate="no">​</a></h4>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> pyobjus </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> autoclass</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">NSString </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> autoclass</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'NSString'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">text </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> NSString</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">alloc</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">initWithUTF8String_</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'Hello world'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">UTF8String</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="getting-os-details">Getting OS details<a href="https://flet.dev/blog/tap-into-native-android-and-ios-apis-with-Pyjnius-and-pyobjus#getting-os-details" class="hash-link" aria-label="Direct link to Getting OS details" title="Direct link to Getting OS details" translate="no">​</a></h4>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> pyobjus </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> autoclass</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> pyobjus</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">dylib_manager </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> load_framework</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> INCLUDE</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Load Foundation framework</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">load_framework</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">INCLUDE</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Foundation</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Get NSProcessInfo instance</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">NSProcessInfo </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> autoclass</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'NSProcessInfo'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">process_info </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> NSProcessInfo</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">processInfo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Retrieve OS version as a string</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">os_version </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> process_info</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">operatingSystemVersionString</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">UTF8String</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string-interpolation string" style="color:#e3116c">f"iOS Version: </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">os_version</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="working-with-app-user-settings">Working with app user settings<a href="https://flet.dev/blog/tap-into-native-android-and-ios-apis-with-Pyjnius-and-pyobjus#working-with-app-user-settings" class="hash-link" aria-label="Direct link to Working with app user settings" title="Direct link to Working with app user settings" translate="no">​</a></h4>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> pyobjus </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> autoclass</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> objc_str</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">NSUserDefaults </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> autoclass</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'NSUserDefaults'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">key </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"pyobjus_hello_world_key"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">value </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Hello, world!"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># set key</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">NSUserDefaults</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">standardUserDefaults</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">setObject_forKey_</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">objc_str</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> objc_str</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">key</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># get key</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ret </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> NSUserDefaults</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">standardUserDefaults</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">stringForKey_</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">objc_str</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">key</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">assert</span><span class="token plain"> ret</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">UTF8String</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> value</span><br></span></code></pre></div></div>
<p>Check complete <a href="https://github.com/flet-dev/python-package-tests/tree/main/pyobjus" target="_blank" rel="noopener noreferrer" class="">Flet Pyobjus example</a>.</p>
<p>For more Pyobjus examples and API refer to the <a href="https://pyobjus.readthedocs.io/en/latest/quickstart.html" target="_blank" rel="noopener noreferrer" class="">Pyobjus Documentation</a>.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="plyer-challenge">Plyer challenge<a href="https://flet.dev/blog/tap-into-native-android-and-ios-apis-with-Pyjnius-and-pyobjus#plyer-challenge" class="hash-link" aria-label="Direct link to Plyer challenge" title="Direct link to Plyer challenge" translate="no">​</a></h2>
<p>There is a <a href="https://github.com/kivy/plyer" target="_blank" rel="noopener noreferrer" class="">Plyer</a> project by Kivy team which uses both Pyjnius and Pyobjus under the hood.</p>
<p>It's not ported to Flet yet. You can either get more usage examples for <a href="https://github.com/kivy/plyer/tree/master/plyer/platforms/android" target="_blank" rel="noopener noreferrer" class="">Android</a> and <a href="https://github.com/kivy/plyer/tree/master/plyer/platforms/ios" target="_blank" rel="noopener noreferrer" class="">iOS</a> from there or help us with porting it to Flet.</p>]]></content>
        <author>
            <name>Feodor Fitsner</name>
            <uri>ttps://github.com/FeodorFitsner</uri>
        </author>
        <category label="news" term="news"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Flet v0.27.0 Release Announcement]]></title>
        <id>https://flet.dev/blog/flet-v-0-27-release-announcement</id>
        <link href="https://flet.dev/blog/flet-v-0-27-release-announcement"/>
        <updated>2025-02-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flet 0.27.0 is now released with exciting new features and improvements!]]></summary>
        <content type="html"><![CDATA[<p>Flet 0.27.0 is now released with exciting new features and improvements!</p>
<ul>
<li class=""><strong>iOS packaging &amp; signing updates</strong> – ensures compliance with App Store Connect verification requirements.</li>
<li class=""><strong>Reduced startup delay</strong> – faster initial launch for desktop applications.</li>
<li class=""><strong>Faster incremental re-builds</strong> – enhances development efficiency with quicker iteration times.</li>
<li class=""><strong>Enhanced Dropdown control</strong> – improved functionality and user experience.</li>
<li class=""><strong>Bug fixes &amp; stability improvements</strong> – various fixes to enhance overall performance and reliability.</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="how-to-upgrade">How to upgrade<a href="https://flet.dev/blog/flet-v-0-27-release-announcement#how-to-upgrade" class="hash-link" aria-label="Direct link to How to upgrade" title="Direct link to How to upgrade" translate="no">​</a></h2>
<p>Run the following command to upgrade Flet:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pip install 'flet[all]' --upgrade</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_BuS1"><p><code>[all]</code> is an "extra" specifier which tells pip to install or upgrade all <code>flet</code> packages: <code>flet</code>, <code>flet-cli</code>, <code>flet-desktop</code> and <code>flet-web</code>.</p></div></div>
<p>Bump <code>flet</code> package version to <code>0.27.0</code> (or remove it at all to use the latest) in your <code>pyproject.toml</code>.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="revamped-ios-packaging">Revamped iOS Packaging<a href="https://flet.dev/blog/flet-v-0-27-release-announcement#revamped-ios-packaging" class="hash-link" aria-label="Direct link to Revamped iOS Packaging" title="Direct link to Revamped iOS Packaging" translate="no">​</a></h2>
<ul>
<li class="">Third-party Flet app dependencies (also known as “site packages” like <code>numpy</code>, <code>pandas</code>, <code>flet</code>, etc.) are now bundled inside a framework, ensuring Xcode signs all files correctly and passes App Store Connect verification.</li>
<li class="">New <code>flet build</code> options for proper iOS package signing.</li>
<li class="">Comprehensive step-by-step documentation for packaging and deploying iOS apps. <a href="https://flet.dev/docs/publish/ios/" target="_blank" rel="noopener noreferrer" class="">Learn more!</a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="enhanced-startup-performance-for-desktop-apps">Enhanced startup performance for desktop apps<a href="https://flet.dev/blog/flet-v-0-27-release-announcement#enhanced-startup-performance-for-desktop-apps" class="hash-link" aria-label="Direct link to Enhanced startup performance for desktop apps" title="Direct link to Enhanced startup performance for desktop apps" translate="no">​</a></h2>
<p>Currently, when packaging for macOS, Windows, and Linux, third-party Flet app dependencies (e.g., numpy, pandas, flet, etc.), also known as <strong>site packages</strong>, are bundled inside the app.zip artifact. This can cause a startup delay, sometimes significant, as the app needs to extract the artifact to the user’s file system before launching.</p>
<p>With Flet 0.27.0, site packages are now copied in an <strong>unpacked state</strong> directly into the application bundle instead of being compressed into app.zip. This change significantly reduces the first launch time.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="faster-incremental-re-builds">Faster incremental re-builds<a href="https://flet.dev/blog/flet-v-0-27-release-announcement#faster-incremental-re-builds" class="hash-link" aria-label="Direct link to Faster incremental re-builds" title="Direct link to Faster incremental re-builds" translate="no">​</a></h2>
<p>If certain parts of the build configuration remain unchanged, the <code>flet build</code> command attempts to skip or optimize specific build pipeline steps (such as re-installing Flet app dependencies), reducing the overall completion time for consecutive builds.</p>
<p>Faster builds mean happier developers! 😄</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="pyodide-0272">Pyodide 0.27.2<a href="https://flet.dev/blog/flet-v-0-27-release-announcement#pyodide-0272" class="hash-link" aria-label="Direct link to Pyodide 0.27.2" title="Direct link to Pyodide 0.27.2" translate="no">​</a></h2>
<p>Pyodide 0.27.2 is based on Python 3.12 and has some serious performance improvements to foreign function interface (FFI).</p>
<p>Flet now supports Python 3.12 across all packaging platforms.</p>
<p>The next stop is Python 3.13!</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="enhanced-dropdown-control">Enhanced <code>Dropdown</code> control.<a href="https://flet.dev/blog/flet-v-0-27-release-announcement#enhanced-dropdown-control" class="hash-link" aria-label="Direct link to enhanced-dropdown-control" title="Direct link to enhanced-dropdown-control" translate="no">​</a></h2>
<p>Since version 0.27.0, Flet uses <a href="https://api.flutter.dev/flutter/material/DropdownMenu-class.html" target="_blank" rel="noopener noreferrer" class="">DropdownMenu</a> flutter widget for <a href="https://flet.dev/docs/controls/dropdown/" target="_blank" rel="noopener noreferrer" class="">Dropdown</a> control, which is a Material 3 version of previously used DropdownButton. Additionally to enhanced look and feel, it allows filter the list based on the text input or search one item in the menu list.</p>
<img src="https://flet.dev/img/docs/controls/dropdown/dropdown-search.gif" class="screenshot-30">
<p>Some properties of previous Dropdown implementation are not available in the new version and were "stubbed" - they will not break your program but don't do anything. See the list of deprecated properties <a href="https://flet.dev/docs/controls/dropdown/" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<p>Previous version of Dropdown control is available as <a href="https://flet.dev/docs/controls/dropdownm2/" target="_blank" rel="noopener noreferrer" class=""><code>DropdownM2</code></a> control and will be removed in Flet 0.30.0.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="-breaking-changes">💥 Breaking changes<a href="https://flet.dev/blog/flet-v-0-27-release-announcement#-breaking-changes" class="hash-link" aria-label="Direct link to 💥 Breaking changes" title="Direct link to 💥 Breaking changes" translate="no">​</a></h2>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="flet-build-command"><code>flet build</code> command<a href="https://flet.dev/blog/flet-v-0-27-release-announcement#flet-build-command" class="hash-link" aria-label="Direct link to flet-build-command" title="Direct link to flet-build-command" translate="no">​</a></h3>
<ul>
<li class=""><code>--team</code> option renamed to <code>--ios-team-id</code>.</li>
<li class=""><code>--include-packages</code> has been removed. Just add extension package into <code>dependencies</code> section of your <code>pyproject.toml</code> file: <a href="https://flet.dev/docs/extend/built-in-extensions/" target="_blank" rel="noopener noreferrer" class="">https://flet.dev/docs/extend/built-in-extensions/</a></li>
<li class=""><code>--cleanup-on-compile</code> removed and two new options added to separate cleanup of app and 3rd-party site packages: <code>--cleanup-app</code> and <code>--cleanup-packages</code>. Two additional options: <code>--cleanup-app-files</code> and <code>--cleanup-package-files</code> work together with <code>--cleanup-*</code> and allow specifying lists of globs to exclude from app and site packages.</li>
<li class=""><code>tool.flet.build_arch</code> renamed to <code>tool.flet.target_arch</code>.</li>
</ul>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="removed-v0240-deprecations">Removed <code>v0.24.0</code> Deprecations<a href="https://flet.dev/blog/flet-v-0-27-release-announcement#removed-v0240-deprecations" class="hash-link" aria-label="Direct link to removed-v0240-deprecations" title="Direct link to removed-v0240-deprecations" translate="no">​</a></h3>
<p>The following items, deprecated in Flet 0.24.0, have been removed: <a href="https://flet.dev/blog/flet-v-0-24-release-announcement#deprecations" target="_blank" rel="noopener noreferrer" class="">https://flet.dev/blog/flet-v-0-24-release-announcement#deprecations</a></p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="cupertinocheckboxinactive_color-property"><code>CupertinoCheckbox.inactive_color</code> property<a href="https://flet.dev/blog/flet-v-0-27-release-announcement#cupertinocheckboxinactive_color-property" class="hash-link" aria-label="Direct link to cupertinocheckboxinactive_color-property" title="Direct link to cupertinocheckboxinactive_color-property" translate="no">​</a></h3>
<p>The <code>inactive_color</code> property of the <a href="https://flet.dev/docs/controls/cupertinocheckbox/" target="_blank" rel="noopener noreferrer" class=""><code>CupertinoCheckbox</code></a> has been removed in favor of <a href="https://flet.dev/docs/controls/cupertinocheckbox/#flet.CupertinoCheckbox.fill_color" target="_blank" rel="noopener noreferrer" class=""><code>fill_color</code></a>.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="other-changes">Other changes<a href="https://flet.dev/blog/flet-v-0-27-release-announcement#other-changes" class="hash-link" aria-label="Direct link to Other changes" title="Direct link to Other changes" translate="no">​</a></h2>
<p>The full list of changes can be found in the <a href="https://github.com/flet-dev/flet/blob/main/CHANGELOG.md" target="_blank" rel="noopener noreferrer" class="">CHANGELOG</a>.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="new-features">New features<a href="https://flet.dev/blog/flet-v-0-27-release-announcement#new-features" class="hash-link" aria-label="Direct link to New features" title="Direct link to New features" translate="no">​</a></h3>
<ul>
<li class="">feat: <code>ReorderableListView</code> Control (<a href="https://github.com/flet-dev/flet/pull/4865" target="_blank" rel="noopener noreferrer" class="">#4865</a>)</li>
<li class="">feat: Implement <code>Container.dark_theme</code> property (<a href="https://github.com/flet-dev/flet/issues/4857" target="_blank" rel="noopener noreferrer" class="">#4857</a>)</li>
<li class="">Upgrade to Pyodide 0.27 for <code>httpx</code> Support (<a href="https://github.com/flet-dev/flet/issues/4840" target="_blank" rel="noopener noreferrer" class="">#4840</a>)</li>
<li class="">Remove <code>CupertinoCheckbox.inactive_color</code> in favor of <code>fill_color</code> (<a href="https://github.com/flet-dev/flet/issues/4837" target="_blank" rel="noopener noreferrer" class="">#4837</a>)</li>
<li class="">feat: <code>flet build</code>: use Provisioning Profile to sign iOS app archive (<code>.ipa</code>), deprecate <code>--team</code> option (<a href="https://github.com/flet-dev/flet/issues/4869" target="_blank" rel="noopener noreferrer" class="">#4869</a>)</li>
<li class="">feat: <code>flet doctor</code> CLI command (<a href="https://github.com/flet-dev/flet/pull/4803" target="_blank" rel="noopener noreferrer" class="">#4803</a>)</li>
<li class="">feat: implement button themes (for <code>ElevatedButton</code>, <code>OutlinedButton</code>, <code>TextButton</code>, <code>FilledButton</code>, <code>IconButton </code>) (<a href="https://github.com/flet-dev/flet/pull/4872" target="_blank" rel="noopener noreferrer" class="">#4872</a>)</li>
<li class="">feat: <code>ControlEvent.data</code> should be of type <code>Optional[str]</code> and default to <code>None</code> (<a href="https://github.com/flet-dev/flet/issues/4786" target="_blank" rel="noopener noreferrer" class="">#4786</a>)</li>
<li class="">feat: <code>flet build</code>: add <code>--source-packages</code> to allow installing certain Python packages from source distros (<a href="https://github.com/flet-dev/flet/issues/4762" target="_blank" rel="noopener noreferrer" class="">#4762</a>)</li>
</ul>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="bug-fixes">Bug fixes<a href="https://flet.dev/blog/flet-v-0-27-release-announcement#bug-fixes" class="hash-link" aria-label="Direct link to Bug fixes" title="Direct link to Bug fixes" translate="no">​</a></h3>
<ul>
<li class="">Fixed: Disable rich's Markup for stdout logs (<a href="https://github.com/flet-dev/flet/issues/4795" target="_blank" rel="noopener noreferrer" class="">#4795</a>)</li>
<li class="">Fixed: Setting <code>SearchBar.bar_border_side</code> isn't visually honoured (<a href="https://github.com/flet-dev/flet/issues/4767" target="_blank" rel="noopener noreferrer" class="">#4767</a>)</li>
<li class="">Fixed: Dropdown: Long options cause the down-arrow to overflow (<a href="https://github.com/flet-dev/flet/issues/4838" target="_blank" rel="noopener noreferrer" class="">#4838</a>)</li>
<li class="">Fixed: CupertinoSlider initialisation does not allow values less then zero/greater then 1 (<a href="https://github.com/flet-dev/flet/issues/4853" target="_blank" rel="noopener noreferrer" class="">#4853</a>)</li>
<li class="">Fixed: Same code shows different appearance in Flet APP/Web/PC local. (<a href="https://github.com/flet-dev/flet/issues/4855" target="_blank" rel="noopener noreferrer" class="">#4855</a>)</li>
<li class="">Fixed: Transforming scale renders a grey screen (<a href="https://github.com/flet-dev/flet/issues/4759" target="_blank" rel="noopener noreferrer" class="">#4759</a>)</li>
<li class="">Fixed: UnicodeDecodeError when using accented characters in manifest.json (<a href="https://github.com/flet-dev/flet/issues/4713" target="_blank" rel="noopener noreferrer" class="">#4713</a>)</li>
<li class="">Fixed: Implement <code>SearchBar.blur()</code> to programmatically unfocus the bar (<a href="https://github.com/flet-dev/flet/issues/4827" target="_blank" rel="noopener noreferrer" class="">#4827</a>)</li>
<li class="">Fixed: Disable markup for flet-cli stdout logs (<a href="https://github.com/flet-dev/flet/pull/4796" target="_blank" rel="noopener noreferrer" class="">#4796</a>)</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="conclusion">Conclusion<a href="https://flet.dev/blog/flet-v-0-27-release-announcement#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>Upgrade to Flet 0.27.0, test your apps and let us know how you find the new features we added.</p>
<p>If you have any questions, please join <a href="https://discord.gg/dzWXP8SHG8" target="_blank" rel="noopener noreferrer" class="">Flet Discord server</a> or create a new thread
on <a href="https://github.com/flet-dev/flet/discussions" target="_blank" rel="noopener noreferrer" class="">Flet GitHub discussions</a>.</p>
<p>Happy Flet-ing! 👾</p>]]></content>
        <author>
            <name>Feodor Fitsner</name>
            <uri>ttps://github.com/FeodorFitsner</uri>
        </author>
        <category label="releases" term="releases"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Flet v0.26.0 Release Announcement]]></title>
        <id>https://flet.dev/blog/flet-v-0-26-release-announcement</id>
        <link href="https://flet.dev/blog/flet-v-0-26-release-announcement"/>
        <updated>2025-01-24T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The Flet 0.26.0 release is here, featuring a significant update to the extensibility approach!]]></summary>
        <content type="html"><![CDATA[<p>The Flet 0.26.0 release is here, featuring a significant update to the extensibility approach!</p>
<p>In summary, a Flet extension is now a single Python package that bundles both Python and Flutter code. This package can be part of your Flet project or hosted in a public Git repository or PyPI.</p>
<p>Built-in Flet extensions, such as <code>Audio</code>, <code>Video</code>, and <code>Map</code>, have been moved to their own repositories. You’re welcome to fork these extensions to create your own or contribute to Flet! These extensions have been published to PyPI, making them easy to include in your Flet app. To use them, simply add the desired extensions to the <code>dependencies</code> section of your <code>pyproject.toml</code> file.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="how-to-upgrade">How to upgrade<a href="https://flet.dev/blog/flet-v-0-26-release-announcement#how-to-upgrade" class="hash-link" aria-label="Direct link to How to upgrade" title="Direct link to How to upgrade" translate="no">​</a></h2>
<p>Run the following command to upgrade Flet:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pip install 'flet[all]' --upgrade</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_BuS1"><p><code>[all]</code> is an "extra" specifier which tells pip to install or upgrade all <code>flet</code> packages: <code>flet</code>, <code>flet-cli</code>, <code>flet-desktop</code> and <code>flet-web</code>.</p></div></div>
<p>Bump <code>flet</code> package version to <code>0.26.0</code> (or remove it at all to use the latest) in your <code>pyproject.toml</code>.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="extensibility-changes">Extensibility changes<a href="https://flet.dev/blog/flet-v-0-26-release-announcement#extensibility-changes" class="hash-link" aria-label="Direct link to Extensibility changes" title="Direct link to Extensibility changes" translate="no">​</a></h2>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="built-in-extensions">Built-in extensions<a href="https://flet.dev/blog/flet-v-0-26-release-announcement#built-in-extensions" class="hash-link" aria-label="Direct link to Built-in extensions" title="Direct link to Built-in extensions" translate="no">​</a></h3>
<p>Flet controls based on 3rd-party Flutter packages that used to be a part of Flet repository, now have been moved to separate repos and published on pypi:</p>
<ul>
<li class=""><a href="https://pypi.org/project/flet-ads/" target="_blank" rel="noopener noreferrer" class="">flet-ads</a></li>
<li class=""><a href="https://pypi.org/project/flet-audio/" target="_blank" rel="noopener noreferrer" class="">flet-audio</a></li>
<li class=""><a href="https://pypi.org/project/flet-audio-recorder/" target="_blank" rel="noopener noreferrer" class="">flet-audio-recorder</a></li>
<li class=""><a href="https://pypi.org/project/flet-flashlight/" target="_blank" rel="noopener noreferrer" class="">flet-flashlight</a></li>
<li class=""><a href="https://pypi.org/project/flet-geolocator/" target="_blank" rel="noopener noreferrer" class="">flet-geolocator</a></li>
<li class=""><a href="https://pypi.org/project/flet-lottie/" target="_blank" rel="noopener noreferrer" class="">flet-lottie</a></li>
<li class=""><a href="https://pypi.org/project/flet-map/" target="_blank" rel="noopener noreferrer" class="">flet-map</a></li>
<li class=""><a href="https://pypi.org/project/flet-permission-handler/" target="_blank" rel="noopener noreferrer" class="">flet-permission-handler</a></li>
<li class=""><a href="https://pypi.org/project/flet-rive/" target="_blank" rel="noopener noreferrer" class="">flet-rive</a></li>
<li class=""><a href="https://pypi.org/project/flet-video/" target="_blank" rel="noopener noreferrer" class="">flet-video</a></li>
<li class=""><a href="https://pypi.org/project/flet-webview/" target="_blank" rel="noopener noreferrer" class="">flet-webview</a></li>
</ul>
<p>To use a built-in Flet extension in your project, add it to the <code>dependencies</code> section of your <code>pyproject.toml</code> file, for example:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">dependencies = [</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  "flet-audio",</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  "flet&gt;=0.26.0",</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">]</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="user-extensions">User extensions<a href="https://flet.dev/blog/flet-v-0-26-release-announcement#user-extensions" class="hash-link" aria-label="Direct link to User extensions" title="Direct link to User extensions" translate="no">​</a></h3>
<p>Flet now makes it easy to create and build projects with your custom controls based on Flutter widgets or Flutter 3rd-party packages:</p>
<ol>
<li class="">
<p>Create new virtual environment and <a href="https://flet.dev/docs/getting-started/installation/#virtual-environment" target="_blank" rel="noopener noreferrer" class="">install Flet</a> there.</p>
</li>
<li class="">
<p>Create new Flet extension project from template:</p>
</li>
</ol>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet create --template extension --project-name my-control</span><br></span></code></pre></div></div>
<p>A project with new MyControl control will be created. The control is just a Flutter Text widget with a single <code>text</code> property.</p>
<ol start="3">
<li class="">Build your app.</li>
</ol>
<p>Flet project created from extension template has <code>examples/my_control_example</code> folder with the example app.</p>
<p>When in the folder where your <code>pyproject.toml</code> for the app is, run <code>flet build</code> command, for example, for macOS:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet build macos -v</span><br></span></code></pre></div></div>
<p>Run the app and see the new custom Flet Control:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">open build/macos/my-control-example.app</span><br></span></code></pre></div></div>
<img src="https://flet.dev/img/blog/extensions/example.png" class="screenshot-30">
<p>Read more about how to customise your extension <a href="https://flet.dev/docs/extend/user-extensions/" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="development-environment-configuration">Development environment configuration<a href="https://flet.dev/blog/flet-v-0-26-release-announcement#development-environment-configuration" class="hash-link" aria-label="Direct link to Development environment configuration" title="Direct link to Development environment configuration" translate="no">​</a></h2>
<p>To enhance the developer experience with the <code>flet build</code> command, Flet 0.26.0 ensures that the correct versions of Flutter SDK, Java (JDK), and Android SDK are installed. If any of these are missing or outdated, it automatically installs them for you.</p>
<p>You still need to install Visual Studio 2022 yourself if you're building a Flet app for Windows, or Xcode if you're building for iOS or macOS.</p>
<p>In the next releases we are going to introduce automatic configuration and startup of Android and iOS emulators.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="flutter-327">Flutter 3.27<a href="https://flet.dev/blog/flet-v-0-26-release-announcement#flutter-327" class="hash-link" aria-label="Direct link to Flutter 3.27" title="Direct link to Flutter 3.27" translate="no">​</a></h2>
<p>Flet has been migrated to Flutter SDK 3.27. See <a href="https://github.com/flet-dev/flet/pull/4703" target="_blank" rel="noopener noreferrer" class="">this pull request</a> for new and updated control properties.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="python-39">Python 3.9<a href="https://flet.dev/blog/flet-v-0-26-release-announcement#python-39" class="hash-link" aria-label="Direct link to Python 3.9" title="Direct link to Python 3.9" translate="no">​</a></h2>
<p>Flet 0.26.0 requires Python 3.9 or later. Python 3.8 has reached <a href="https://devguide.python.org/versions/" target="_blank" rel="noopener noreferrer" class="">EOL</a>.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="other-changes">Other changes<a href="https://flet.dev/blog/flet-v-0-26-release-announcement#other-changes" class="hash-link" aria-label="Direct link to Other changes" title="Direct link to Other changes" translate="no">​</a></h2>
<ul>
<li class="">Optional on-demand creation of <code>ListView.controls</code> (<a href="https://github.com/flet-dev/flet/issues/3931" target="_blank" rel="noopener noreferrer" class="">#3931</a>)</li>
<li class="">Reset <code>InteractiveViewer</code> transformations (<a href="https://github.com/flet-dev/flet/issues/4391" target="_blank" rel="noopener noreferrer" class="">#4391</a>)</li>
<li class="">Passthrough of mouse events from main window to other applications (<a href="https://github.com/flet-dev/flet/issues/1438" target="_blank" rel="noopener noreferrer" class="">#1438</a>)</li>
<li class="">Implemented <code>Window.ignore_mouse_events</code> (<a href="https://github.com/flet-dev/flet/pull/4465" target="_blank" rel="noopener noreferrer" class="">#4465</a>)</li>
<li class="">Adding Google/Android TV platform support (<a href="https://github.com/flet-dev/flet/pull/4581" target="_blank" rel="noopener noreferrer" class="">#4581</a>)</li>
<li class="">Remove <code>Optional[]</code> from predefined typing <code>*Value</code>s (<a href="https://github.com/flet-dev/flet/pull/4702" target="_blank" rel="noopener noreferrer" class="">#4702</a>)</li>
<li class="">Throttle <code>InteractiveViewer</code> update events (<a href="https://github.com/flet-dev/flet/pull/4704" target="_blank" rel="noopener noreferrer" class="">#4704</a>)</li>
<li class="">Remove v0.26.0-related deprecations (<a href="https://github.com/flet-dev/flet/issues/4456" target="_blank" rel="noopener noreferrer" class="">#4456</a>)</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="bug-fixes">Bug fixes<a href="https://flet.dev/blog/flet-v-0-26-release-announcement#bug-fixes" class="hash-link" aria-label="Direct link to Bug fixes" title="Direct link to Bug fixes" translate="no">​</a></h2>
<ul>
<li class="">Fixed: Update project_dependencies.py (<a href="https://github.com/flet-dev/flet/pull/4459" target="_blank" rel="noopener noreferrer" class="">#4459</a>)</li>
<li class="">Fixed: <code>SafeArea</code> object has no attribute <code>_SafeArea__minimum</code> (<a href="https://github.com/flet-dev/flet/pull/4500" target="_blank" rel="noopener noreferrer" class="">#4500</a>)</li>
<li class="">Fixed: Tooltip corruption in <code>Segment</code> and <code>BarChartRod</code> on <code>update()</code> (<a href="https://github.com/flet-dev/flet/pull/4525" target="_blank" rel="noopener noreferrer" class="">#4525</a>)</li>
<li class="">Fixed: Setting <code>CheckBox.border_side.stroke_align</code> to an Enum fails (<a href="https://github.com/flet-dev/flet/pull/4526" target="_blank" rel="noopener noreferrer" class="">#4526</a>)</li>
<li class="">Fixed: <code>ControlState</code> should be resolved based on user-defined order (<a href="https://github.com/flet-dev/flet/pull/4556" target="_blank" rel="noopener noreferrer" class="">#4556</a>)</li>
<li class="">Fixed: broken <code>Dismissible.dismiss_direction</code> (<a href="https://github.com/flet-dev/flet/pull/4557" target="_blank" rel="noopener noreferrer" class="">#4557</a>)</li>
<li class="">Fixed: Fix Rive not updating (<a href="https://github.com/flet-dev/flet/pull/4582" target="_blank" rel="noopener noreferrer" class="">#4582</a>)</li>
<li class="">Fixed: <code>DatePicker</code> regression with first and last dates (<a href="https://github.com/flet-dev/flet/pull/4661" target="_blank" rel="noopener noreferrer" class="">#4661</a>)</li>
<li class=""><code>flet build</code> command: Copy <code>flutter-packages</code>, support for platform-specific dependencies (<a href="https://github.com/flet-dev/flet/pull/4667" target="_blank" rel="noopener noreferrer" class="">#4667</a>)</li>
<li class="">Fixed: <code>CupertinoBottomSheet</code> applies a red color and yellow underline to <code>Text</code>  content (<a href="https://github.com/flet-dev/flet/pull/4673" target="_blank" rel="noopener noreferrer" class="">#4673</a>)</li>
<li class="">Fixed: setting <code>ButtonTheme</code> displays a grey screen (<a href="https://github.com/flet-dev/flet/pull/4731" target="_blank" rel="noopener noreferrer" class="">#4731</a>)</li>
<li class="">Fixed: <code>Textfield</code> input border color considers user-specified <code>border_color</code> property (<a href="https://github.com/flet-dev/flet/pull/4735" target="_blank" rel="noopener noreferrer" class="">#4735</a>)</li>
<li class="">Fixed: make <code>Tooltip.message</code> a required parameter (<a href="https://github.com/flet-dev/flet/pull/4736" target="_blank" rel="noopener noreferrer" class="">#4736</a>)</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="conclusion">Conclusion<a href="https://flet.dev/blog/flet-v-0-26-release-announcement#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>Upgrade to Flet 0.26.0, test your apps and let us know how you find the new features we added.</p>
<p>If you have any questions, please join <a href="https://discord.gg/dzWXP8SHG8" target="_blank" rel="noopener noreferrer" class="">Flet Discord server</a> or create a new thread
on <a href="https://github.com/flet-dev/flet/discussions" target="_blank" rel="noopener noreferrer" class="">Flet GitHub discussions</a>.</p>
<p>Happy Flet-ing! 👾</p>]]></content>
        <author>
            <name>Feodor Fitsner</name>
            <uri>ttps://github.com/FeodorFitsner</uri>
        </author>
        <category label="releases" term="releases"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Flet v0.25.0 Release Announcement]]></title>
        <id>https://flet.dev/blog/flet-v-0-25-release-announcement</id>
        <link href="https://flet.dev/blog/flet-v-0-25-release-announcement"/>
        <updated>2024-11-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Hey Flet developers, we’ve got something exciting to share — Flet 0.25.0 is officially released!]]></summary>
        <content type="html"><![CDATA[<p>Hey Flet developers, we’ve got something exciting to share — Flet 0.25.0 is officially released!</p>
<p>The biggest news? No more Kivy for iOS and Android packaging. No more dealing with frustrating Python binary dependencies — Flet now uses its own custom Python runtime, so your app builds are easier than ever. Plus, we’ve added loads of new features like better permissions control, faster rebuilds, and even a lightweight Linux client that skips the bloat.</p>
<p>Let’s dive into all the cool stuff Flet 0.25.0 has to offer! 🚀</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="how-to-upgrade">How to upgrade<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#how-to-upgrade" class="hash-link" aria-label="Direct link to How to upgrade" title="Direct link to How to upgrade" translate="no">​</a></h2>
<p>Run the following command to upgrade Flet:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pip install 'flet[all]' --upgrade</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_BuS1"><p><code>[all]</code> is an "extra" specifier which tells pip to install all <code>flet</code> package dependencies. See <a href="https://flet.dev/blog/flet-v-0-25-release-announcement#new-python-packages-structure" class="">New Python packages structure</a> section below for the explanation.</p></div></div>
<p>Bump <code>flet</code> package version to <code>0.25.0</code> (or remove it at all to use the latest) in <code>requirements.txt</code> or <code>pyproject.toml</code>.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="new-packaging">New packaging<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#new-packaging" class="hash-link" aria-label="Direct link to New packaging" title="Direct link to New packaging" translate="no">​</a></h2>
<p>Flet packaging for iOS and Android has been relying on Kivy and it was super annoying when your app depends on Python binary packages, such as Numpy or Pillow. You needed to compile those packages yourself using Kivy command line tools. It was really frustrating and even hopeless if Kivy didn't have "recipes" for some packages, like Pydantic.</p>
<p>Flet does not depend on Kivy anymore and uses its own Python runtime "meticulously crafted in-house".</p>
<p>Flet packaging implementation for iOS and Android adheres to strict specifications defined in <a href="https://peps.python.org/pep-0730/" target="_blank" rel="noopener noreferrer" class="">PEP 730</a> (iOS) and <a href="https://peps.python.org/pep-0738/" target="_blank" rel="noopener noreferrer" class="">PEP 738</a> (Android) which were implemented and released in Python 3.13 (and back-ported to Python 3.12). When pypi.org supports wheel tags for iOS and Android and 3rd-party Python package maintainers start uploading their mobile packages Flet will be compatible with them and you'll be able to use them in your Flet app.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="pre-built-binary-packages">Pre-built binary packages<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#pre-built-binary-packages" class="hash-link" aria-label="Direct link to Pre-built binary packages" title="Direct link to Pre-built binary packages" translate="no">​</a></h3>
<p><code>flet build</code> command for iOS and Android is now installing pre-built binary packages from <a href="https://pypi.flet.dev/" target="_blank" rel="noopener noreferrer" class="">https://pypi.flet.dev</a>.</p>
<p>New packages can be built with creating a recipe in <a href="https://github.com/flet-dev/mobile-forge" target="_blank" rel="noopener noreferrer" class="">Mobile Forge</a> project. For now, Flet team is authoring those recipes for you, but when the process is polished and fully-automated you'll be able to send a PR and test the compiled package right away.</p>
<p>If you don't yet see a package you require at <a href="https://pypi.flet.dev/" target="_blank" rel="noopener noreferrer" class="">https://pypi.flet.dev</a>, you can request it in <a href="https://github.com/flet-dev/flet/discussions/categories/packages" target="_blank" rel="noopener noreferrer" class="">Flet discussions - Packages</a>. Please do not request pure Python packages. Go to package's "Download files" section at <a href="https://pypi.org/" target="_blank" rel="noopener noreferrer" class="">https://pypi.org</a> and make sure it contains binary platform-specific wheels.</p>
<p>Packaging behavior was changed too:</p>
<ul>
<li class="">The packaging is not trying to replace <code>flet</code> dependency with <code>flet-runtime</code>, <code>flet-embed</code> or <code>flet-pyodide</code>, but install all dependencies "as is" from <code>requirements.txt</code> or <code>pyproject.toml</code> - thanks to the <a href="https://flet.dev/blog/flet-v-0-25-release-announcement#new-python-packages-structure" class="">new Flet packages structure</a>.</li>
<li class="">If the binary package for target platform is not found the packaging won't be trying to compile it from source distribution, but will fail instead with a meaningful error.</li>
</ul>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="python-312">Python 3.12<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#python-312" class="hash-link" aria-label="Direct link to Python 3.12" title="Direct link to Python 3.12" translate="no">​</a></h3>
<p>Packaged Flet app runs on Python 3.12.7 runtime on all platforms.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="permissions">Permissions<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#permissions" class="hash-link" aria-label="Direct link to Permissions" title="Direct link to Permissions" translate="no">​</a></h3>
<p>New <code>flet build</code> command allows granular control over permissions, features and entitlements embedded into <code>AndroidManifest.xml</code>, <code>Info.plist</code> and <code>.entitlements</code> files.</p>
<p>No more hard-coded permissions in those files!</p>
<p>For example, setting permissions for iOS bundle:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet build --info-plist NSLocationWhenInUseUsageDescription="This app uses location service when in use."</span><br></span></code></pre></div></div>
<p>or the same in <code>pyproject.toml</code> (read about <code>pyproject.toml</code> support below):</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.ios.info] # --info-plist</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">NSLocationWhenInUseUsageDescription = "This app uses location service when in use."</span><br></span></code></pre></div></div>
<p>An example of setting Android permissions and features:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet build \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    --android-permissions android.permission.READ_EXTERNAL_STORAGE=True \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      android.permission.WRITE_EXTERNAL_STORAGE=True \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    --android-features android.hardware.location.network=False</span><br></span></code></pre></div></div>
<p><a href="https://flet.dev/docs/publish/#permissions" target="_blank" rel="noopener noreferrer" class="">Read more about permissions in the docs</a>.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="control-over-app-compilation-and-cleanup">Control over app compilation and cleanup<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#control-over-app-compilation-and-cleanup" class="hash-link" aria-label="Direct link to Control over app compilation and cleanup" title="Direct link to Control over app compilation and cleanup" translate="no">​</a></h3>
<p><code>flet build</code> command is no longer compiling app <code>.py</code> files into <code>.pyc</code> by default which allows you to defer discovery of any syntax errors in your app and complete the packaging.</p>
<p>You can control the compilation and cleanup with the following new options:</p>
<ul>
<li class=""><code>--compile-app</code> - compile app's <code>.py</code> files.</li>
<li class=""><code>--compile-packages</code> - compile installed packages' <code>.py</code> files.</li>
<li class=""><code>--cleanup-on-compile</code> - remove unnecessary files upon successful compilation.</li>
</ul>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="signing-android-bundles">Signing Android bundles<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#signing-android-bundles" class="hash-link" aria-label="Direct link to Signing Android bundles" title="Direct link to Signing Android bundles" translate="no">​</a></h3>
<p>We also added new options for signing Android builds:</p>
<ul>
<li class=""><code>--android-signing-key-store</code> - path to an upload keystore <code>.jks</code> file for Android apps.</li>
<li class=""><code>--android-signing-key-store-password</code> - Android signing store password.</li>
<li class=""><code>--android-signing-key-alias</code> - Android signing key alias. Default is "upload".</li>
<li class=""><code>--android-signing-key-password</code> - Android signing key password.</li>
</ul>
<p>Read <a href="https://docs.flutter.dev/deployment/android#signing-the-app" target="_blank" rel="noopener noreferrer" class="">Build and release an Android app</a> for more information on how to configure upload key for Android builds.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="deep-linking-configuration">Deep linking configuration<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#deep-linking-configuration" class="hash-link" aria-label="Direct link to Deep linking configuration" title="Direct link to Deep linking configuration" translate="no">​</a></h3>
<p>There is a new <code>--deep-linking-url</code> option to configure deep linking for iOS and Android builds. The value must be in the format <code>&lt;scheme&gt;://&lt;host&gt;</code>.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="faster-re-builds">Faster re-builds<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#faster-re-builds" class="hash-link" aria-label="Direct link to Faster re-builds" title="Direct link to Faster re-builds" translate="no">​</a></h3>
<p>Ephemeral Flutter app created by <code>flet build</code> command is no longer being re-created on every build in a temp directory, but cached in <code>build/flutter</code> directory which gives faster re-builds, improves packaging troubleshooting and does not pollute user temp directory.</p>
<p>You can use <code>--clear-cache</code> option to do a clean build though.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="split-apks-per-abi">Split APKs per ABI<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#split-apks-per-abi" class="hash-link" aria-label="Direct link to Split APKs per ABI" title="Direct link to Split APKs per ABI" translate="no">​</a></h3>
<p><code>flet build</code> now provides the built-in <code>--split-per-abi</code> option to split the APKs per ABIs.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="data-and-temp-directories-for-the-app">"Data" and "Temp" directories for the app<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#data-and-temp-directories-for-the-app" class="hash-link" aria-label="Direct link to &quot;Data&quot; and &quot;Temp&quot; directories for the app" title="Direct link to &quot;Data&quot; and &quot;Temp&quot; directories for the app" translate="no">​</a></h2>
<p>Flet developers have been asking where to store application data, such as uploaded files, SQLite databases, etc. that are persistent across application updates.</p>
<p>This release introduce two environment variables that are available in your Flet apps:</p>
<ul>
<li class=""><code>FLET_APP_STORAGE_DATA</code> - directory for storing application data that is preserved between app updates. That directory is already pre-created and its location depends on the platform the app is running on.</li>
<li class=""><code>FLET_APP_STORAGE_TEMP</code> - directory for temporary application files, i.e. cache. That directory is already pre-created and its location depends on the platform the app is running on.</li>
</ul>
<p>For example, data folder path can be read in your app as:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">import os</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># it's `None` when running the app in web mode</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">data_dir = os.getenv("FLET_APP_STORAGE_DATA")</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_BuS1"><p><code>flet run</code> command creates data and temp directories and sets <code>FLET_APP_STORAGE_DATA</code> and <code>FLET_APP_STORAGE_TEMP</code> to their paths.</p></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="pyprojecttoml-support"><code>pyproject.toml</code> support<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#pyprojecttoml-support" class="hash-link" aria-label="Direct link to pyprojecttoml-support" title="Direct link to pyprojecttoml-support" translate="no">​</a></h2>
<p>It's inconvenient and bulky to carry all <code>flet build</code> settings as command line options.</p>
<p>In Flet 0.25.0 release is now possible to configure <code>flet build</code>, <code>flet run</code>, and <code>flet publish</code> settings in <code>pyproject.toml</code>!</p>
<p>Flet adds <code>tool.flet</code> section and sub-sections to <code>pyproject.toml</code>. Here's the minimal version of <code>pyproject.toml</code> you can put into root folder of your app:</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[project]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">name = "my_app"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">version = "1.0.0"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">description = "My first Flet project"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">authors = [</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  {name = "John Smith", email = "john@email.com"}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">dependencies = ["flet"]</span><br></span></code></pre></div></div>
<p>You can also generate a starting <code>pyproject.toml</code> (and other files) for your project with <code>flet create</code> command.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="new-python-packages-structure">New Python packages structure<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#new-python-packages-structure" class="hash-link" aria-label="Direct link to New Python packages structure" title="Direct link to New Python packages structure" translate="no">​</a></h2>
<p>We re-factored Flet Python packages and removed <code>flet-core</code>, <code>flet-runtime</code>, <code>flet-embed</code> or<code>flet-pyodide</code> packages.</p>
<p>The new structure avoids rewriting pip dependencies while installing <code>flet</code> package on various platforms. There was a problem of detecting the correct <code>flet</code> package to install (<code>flet-runtime</code>, <code>flet-embed</code> or<code>flet-pyodide</code>?) if <code>flet</code> was not a direct dependency in user's app.</p>
<p>New Flet packages:</p>
<ul>
<li class=""><code>flet</code> - required for minimal Flet setup, app entry point for various platforms with core logic and controls. Installed on all platforms.</li>
<li class=""><code>flet-cli</code> - contains Flet CLI commands. Installed on desktop only.</li>
<li class=""><code>flet-desktop</code> - contains pre-built Flet "client" app binary for macOS, Windows and Linux. By default installed on macOS and Windows desktops only.</li>
<li class=""><code>flet-desktop-light</code> - contains a light-weight version (without Audio and Video controls) of Flet "client" for Linux. By default installed on Linux desktops only.</li>
<li class=""><code>flet-web</code> - contains Flet web "client" and FastAPI integration. Installed on desktop only.</li>
</ul>
<p>Packaged Flet app contains only <code>flet</code> package now.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="flet-package-extras"><code>flet</code> package extras<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#flet-package-extras" class="hash-link" aria-label="Direct link to flet-package-extras" title="Direct link to flet-package-extras" translate="no">​</a></h3>
<p><code>flet</code> package defines the following extras that can be specified when installing Flet with pip, uv, poetry and other package manager:</p>
<ul>
<li class=""><code>flet[all]</code> - installs <code>flet</code>, <code>flet-cli</code>, <code>flet-desktop</code> and <code>flet-web</code>. Recommended for development.</li>
<li class=""><code>flet[cli]</code> - installs <code>flet</code> and <code>flet-cli</code>. Can be used in CI environment for packaging only.</li>
<li class=""><code>flet[web]</code> - installs <code>flet</code> and <code>flet-web</code>. Used for deploying Flet web apps.</li>
<li class=""><code>flet[desktop]</code> - installs <code>flet</code> and <code>flet-desktop</code>. Used for desktop-only development.</li>
</ul>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="new-flet-install-and-upgrade-commands">New Flet install and upgrade commands<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#new-flet-install-and-upgrade-commands" class="hash-link" aria-label="Direct link to New Flet install and upgrade commands" title="Direct link to New Flet install and upgrade commands" translate="no">​</a></h3>
<p>Starting from this release the development version of <code>flet</code> package should be installed with the following command:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pip install 'flet[all]'</span><br></span></code></pre></div></div>
<p>Upgrading <code>flet</code> package:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pip install 'flet[all]' --upgrade</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_BuS1"><p><code>pip install flet</code> still works too, but it will install <code>flet</code> package only and dependent packages will be installed on demand. For example, when you run any <code>flet</code> CLI command <code>flet-cli</code> will be installed, or when you run <code>flet run</code> command <code>flet-desktop</code> package will be installed.</p></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="light-client-for-linux">"Light" client for Linux<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#light-client-for-linux" class="hash-link" aria-label="Direct link to &quot;Light&quot; client for Linux" title="Direct link to &quot;Light&quot; client for Linux" translate="no">​</a></h2>
<p>A lightweight desktop client, without Audio and Video controls, is now installed on Linux by default. It improves initial user experience as user doesn't need to immediately deal with <code>gstreamer</code> (audio) and <code>mpv</code> (video) dependencies and Flet "just works".</p>
<p>Once user got some Flet experience and wants to use Video and Audio controls in their application they can install gstreamer and/or mpv and replace Flet desktop with a full version.</p>
<p>Uninstall "light" Flet client:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pip uninstall flet-desktop-light --yes</span><br></span></code></pre></div></div>
<p>Install full Flet desktop client:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pip install flet-desktop</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="new-controls">New controls<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#new-controls" class="hash-link" aria-label="Direct link to New controls" title="Direct link to New controls" translate="no">​</a></h2>
<ul>
<li class="">Mobile Ads (<code>Banner</code> and <code>Interstitial</code>) (<a href="https://github.com/flet-dev/flet/pull/3288" target="_blank" rel="noopener noreferrer" class="">details and example</a>).</li>
<li class=""><code>Button</code> control (<a href="https://github.com/flet-dev/flet/pull/4265" target="_blank" rel="noopener noreferrer" class="">#4265</a>) - which is just an alias for <code>ElevatedButton</code> control.</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="breaking-changes">Breaking changes<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#breaking-changes" class="hash-link" aria-label="Direct link to Breaking changes" title="Direct link to Breaking changes" translate="no">​</a></h2>
<ul>
<li class="">Refactor <code>Badge</code> Control to a Dataclass; added new <code>badge</code> property to all controls (<a href="https://github.com/flet-dev/flet/pull/4077" target="_blank" rel="noopener noreferrer" class="">#4077</a>).</li>
</ul>
<p>Below is how to migrate:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># before</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">navigation_bar </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">NavigationBar</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        destinations</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">NavigationBarDestination</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                icon_content</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Badge</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    content</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Icon</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Icons</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">PHONE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    text</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                label</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"Calls"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># after</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">navigation_bar </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">NavigationBar</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        destinations</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">NavigationBarDestination</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                  icon</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Icon</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                        ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Icons</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">PHONE</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                        badge</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"10"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                label</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"Calls"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="other-changes">Other changes<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#other-changes" class="hash-link" aria-label="Direct link to Other changes" title="Direct link to Other changes" translate="no">​</a></h2>
<ul>
<li class="">Added <code>{value_length}</code>, <code>{max_length}</code>, and <code>{symbols_left}</code> placeholders to <code>TextField.counter_text</code> (<a href="https://github.com/flet-dev/flet/pull/4403" target="_blank" rel="noopener noreferrer" class="">#4403</a>).</li>
<li class="">Added <code>--skip-flutter-doctor</code> to build cli command (<a href="https://github.com/flet-dev/flet/pull/4388" target="_blank" rel="noopener noreferrer" class="">#4388</a>).</li>
<li class=""><code>WebView</code> enhancements (<a href="https://github.com/flet-dev/flet/pull/4018" target="_blank" rel="noopener noreferrer" class="">#4018</a>).</li>
<li class=""><code>Map</code> control enhancements (<a href="https://github.com/flet-dev/flet/pull/3994" target="_blank" rel="noopener noreferrer" class="">#3994</a>).</li>
<li class="">Exposed more <code>Theme</code> props (<a href="https://github.com/flet-dev/flet/pull/4278" target="_blank" rel="noopener noreferrer" class="">#4278</a>, <a href="https://github.com/flet-dev/flet/pull/4278" target="_blank" rel="noopener noreferrer" class="">#4278</a>).</li>
<li class="">Exposed more properties in multiple Controls (<a href="https://github.com/flet-dev/flet/pull/4105" target="_blank" rel="noopener noreferrer" class="">#4105</a>)</li>
<li class="">Added <code>__contains__</code> methods in container-alike Controls (<a href="https://github.com/flet-dev/flet/pull/4374" target="_blank" rel="noopener noreferrer" class="">#4374</a>).</li>
<li class="">Added a custom <code>Markdown</code> code theme (<a href="https://github.com/flet-dev/flet/pull/4343" target="_blank" rel="noopener noreferrer" class="">#4343</a>).</li>
<li class="">Added <code>barrier_color</code> prop to dialogs (<a href="https://github.com/flet-dev/flet/pull/4236" target="_blank" rel="noopener noreferrer" class="">#4236</a>).</li>
<li class="">Merged <code>icon</code> and <code>icon_content</code> props into <code>icon: str | Control</code> (<a href="https://github.com/flet-dev/flet/pull/4305" target="_blank" rel="noopener noreferrer" class="">#4305</a>).</li>
<li class="">Migrated <code>colors</code> and <code>icons</code> variables to Enums (<a href="https://github.com/flet-dev/flet/pull/4180" target="_blank" rel="noopener noreferrer" class="">#4180</a>).</li>
<li class="">TextField: <code>suffix_icon</code>, <code>prefix_icon</code> and <code>icon</code> can be <code>Control</code> or <code>str</code> (<a href="https://github.com/flet-dev/flet/pull/4173" target="_blank" rel="noopener noreferrer" class="">#4173</a>).</li>
<li class="">Added <code>--pyinstaller-build-args</code> to <code>flet pack</code> CLI command (<a href="https://github.com/flet-dev/flet/pull/4187" target="_blank" rel="noopener noreferrer" class="">#4187</a>).</li>
<li class="">Made SearchBar's view height adjustable; added new properties (<a href="https://github.com/flet-dev/flet/pull/4039" target="_blank" rel="noopener noreferrer" class="">#4039</a>).</li>
<li class="">Bumped Rive version and fixed Linux app build template for <code>rive_common</code>.</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="bug-fixes">Bug fixes<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#bug-fixes" class="hash-link" aria-label="Direct link to Bug fixes" title="Direct link to Bug fixes" translate="no">​</a></h2>
<ul>
<li class="">Fixed <code>Icon</code> rotation (<a href="https://github.com/flet-dev/flet/pull/4384" target="_blank" rel="noopener noreferrer" class="">#4384</a>).</li>
<li class="">Fixed regression in <code>Markdown.code_theme</code> when using <code>MarkdownCodeTheme</code> enum (<a href="https://github.com/flet-dev/flet/pull/4373" target="_blank" rel="noopener noreferrer" class="">#4373</a>).</li>
<li class="">Fixed <code>Segment</code> and <code>NavigationBarDestination</code> accept only string tooltips (<a href="https://github.com/flet-dev/flet/pull/4326" target="_blank" rel="noopener noreferrer" class="">#4326</a>).</li>
<li class="">Display informative message when <code>date</code> has wrong format (<a href="https://github.com/flet-dev/flet/pull/4019" target="_blank" rel="noopener noreferrer" class="">#4019</a>).</li>
<li class="">Fixed <code>MapConfiguration.interaction_configuration</code> is not honoured (<a href="https://github.com/flet-dev/flet/pull/3976" target="_blank" rel="noopener noreferrer" class="">#3976</a>).</li>
<li class="">Fixed <code>Video.jump_to()</code> fails with negative indexes (<a href="https://github.com/flet-dev/flet/pull/4294" target="_blank" rel="noopener noreferrer" class="">#4294</a>).</li>
<li class="">Fixed condition in <code>AppBar.tooltip_opacity</code> (<a href="https://github.com/flet-dev/flet/pull/4280" target="_blank" rel="noopener noreferrer" class="">#4280</a>).</li>
<li class="">Fixed wrong type (asyncio.Future -&gt; concurrent.futures.Future) and handle <code>CancelledError</code> (<a href="https://github.com/flet-dev/flet/pull/4268" target="_blank" rel="noopener noreferrer" class="">#4268</a>).</li>
<li class="">Fixed clicking on <code>CupertinoContextMenuAction</code> doesn't close context menu (<a href="https://github.com/flet-dev/flet/pull/3948" target="_blank" rel="noopener noreferrer" class="">#3948</a>).</li>
<li class="">Fixed dropdown <code>max_menu_height</code> (<a href="https://github.com/flet-dev/flet/pull/3974" target="_blank" rel="noopener noreferrer" class="">#3974</a>).</li>
<li class="">Fixed prevent button style from being modified in <code>before_update()</code> (<a href="https://github.com/flet-dev/flet/pull/4181" target="_blank" rel="noopener noreferrer" class="">#4181</a>).</li>
<li class="">Fixed disabling filled buttons is not visually respected (<a href="https://github.com/flet-dev/flet/pull/4090" target="_blank" rel="noopener noreferrer" class="">#4090</a>).</li>
<li class="">when <code>label</code> is set, use <code>MainAxisSize.min</code> for the <code>Row</code> (<a href="https://github.com/flet-dev/flet/pull/3998" target="_blank" rel="noopener noreferrer" class="">#3998</a>).</li>
<li class="">Fixed <code>NavigationBarDestination.disabled</code> has no visual effect (<a href="https://github.com/flet-dev/flet/pull/4073" target="_blank" rel="noopener noreferrer" class="">#4073</a>).</li>
<li class="">Fixed autofill in <code>CupertinoTextField</code> (<a href="https://github.com/flet-dev/flet/pull/4103" target="_blank" rel="noopener noreferrer" class="">#4103</a>).</li>
<li class="">Linechart: <code>jsonDecode</code> tooltip before displaying (<a href="https://github.com/flet-dev/flet/pull/4069" target="_blank" rel="noopener noreferrer" class="">#4069</a>).</li>
<li class="">Fixed button's <code>bgcolor</code>, <code>color</code> and <code>elevation</code> (<a href="https://github.com/flet-dev/flet/pull/4126" target="_blank" rel="noopener noreferrer" class="">#4126</a>).</li>
<li class="">Fixed scrolling issues on Windows (<a href="https://github.com/flet-dev/flet/pull/4145" target="_blank" rel="noopener noreferrer" class="">#4145</a>).</li>
<li class="">Skip running flutter doctor on windows if <code>no_rich_output</code> is <code>True</code> (<a href="https://github.com/flet-dev/flet/pull/4108" target="_blank" rel="noopener noreferrer" class="">#4108</a>).</li>
<li class="">Fixed <code>TextField</code> freezes on Linux Mint #4422](<a href="https://github.com/flet-dev/flet/pull/4422" target="_blank" rel="noopener noreferrer" class="">https://github.com/flet-dev/flet/pull/4422</a>)).</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="conclusion">Conclusion<a href="https://flet.dev/blog/flet-v-0-25-release-announcement#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>Flet 0.25.0 is a huge release and your feedback is highly welcomed!</p>
<p>Upgrade to Flet 0.25.0, test your apps and let us know how you find the new features we added.</p>
<p>If you have any questions, please join <a href="https://discord.gg/dzWXP8SHG8" target="_blank" rel="noopener noreferrer" class="">Flet Discord server</a> or create a new thread
on <a href="https://github.com/flet-dev/flet/discussions" target="_blank" rel="noopener noreferrer" class="">Flet GitHub discussions</a>.</p>
<p>Happy Flet-ing! 👾</p>]]></content>
        <author>
            <name>Feodor Fitsner</name>
            <uri>ttps://github.com/FeodorFitsner</uri>
        </author>
        <category label="releases" term="releases"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[pyproject.toml support for flet build command]]></title>
        <id>https://flet.dev/blog/pyproject-toml-support-for-flet-build-command</id>
        <link href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command"/>
        <updated>2024-10-15T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The number of options for flet build command grew substantially over the time and it's been inconvenient to carry all these settings in a command line.]]></summary>
        <content type="html"><![CDATA[<p>The number of options for <code>flet build</code> command grew substantially over the time and it's been inconvenient to carry all these settings in a command line.</p>
<p>Today, we are excited to announce another Flet pre-release which now allows configuring app build settings in <code>pyproject.toml</code>!</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="installing-pre-release">Installing pre-release<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#installing-pre-release" class="hash-link" aria-label="Direct link to Installing pre-release" title="Direct link to Installing pre-release" translate="no">​</a></h2>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pip install flet==0.25.0.dev3526</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_BuS1"><p>For testing purposes we suggest installing Flet pre-release in a dedicated Python virtual environment.</p></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="building-the-app-with-pre-release">Building the app with pre-release<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#building-the-app-with-pre-release" class="hash-link" aria-label="Direct link to Building the app with pre-release" title="Direct link to Building the app with pre-release" translate="no">​</a></h2>
<p>To build your app with <code>flet build</code> command and pre-release version of Flet make sure your <code>requirements.txt</code> either contains exact version specifier:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet==0.25.0.dev3526</span><br></span></code></pre></div></div>
<p>or <code>--pre</code> flag before <code>flet</code> dependency:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">--pre</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">flet</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="quick-start">Quick start<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#quick-start" class="hash-link" aria-label="Direct link to Quick start" title="Direct link to Quick start" translate="no">​</a></h2>
<p>Create the following minimal <code>pyproject.toml</code> file in the root of your Flet app or run <code>flet create</code> to create a new app from template:</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[project]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">name = "my_app"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">version = "1.0.0"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">description = "My first Flet project"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">authors = [</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  {name = "John Smith", email = "john@email.com"}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">dependencies = ["flet==0.25.0.dev3526"]</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_BuS1"><p>With <code>pyproject.toml</code>, you no longer need <code>requirements.txt</code>. However, if a <code>requirements.txt</code> file exists in the app's directory, the flet build command will prioritize reading dependencies from it instead of those listed in <code>pyproject.toml</code>.</p></div></div>
<p><code>[project]</code> is the standard required section of <code>project.toml</code>.</p>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_BuS1"><p>Flet also supports <code>[tool.poetry]</code> section created by Poetry which contains project settings.</p></div></div>
<p>A minimal <code>pyproject.toml</code> for Poetry, which is also supported by <code>flet build</code> command, is the following:</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.poetry]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">name = "my_app"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">version = "1.0.0"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">description = "My first Flet project"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">authors = ["John Smith &lt;john@email.com&gt;"]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[tool.poetry.dependencies]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">python = "^3.10"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">flet = "0.25.0.dev3526"</span><br></span></code></pre></div></div>
<p><code>project.name</code> (or <code>tool.poetry.name</code>) corresponds to <code>--project</code> option of <code>flet build</code> command and it will be the name of app bundle or executable. The value of <code>project.name</code> will be "slugified" where all non-alphanumeric values are replaced with dashes <code>-</code>.</p>
<p><code>project.version</code> (or <code>tool.poetry.version</code>) corresponds to <code>--build-version</code> option and it is a value in "x.y.z" string used as the version number shown to users.</p>
<p><code>project.description</code> (or <code>tool.poetry.description</code>) corresponds to <code>--description</code> option which is the description to use for executable or bundle.</p>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_BuS1"><p><code>project.authors</code> and <code>tool.poetry.authors</code> are not used by <code>flet build</code>, but required by a standard and other tools.</p></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="overriding-config-with-cli-options">Overriding config with CLI options<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#overriding-config-with-cli-options" class="hash-link" aria-label="Direct link to Overriding config with CLI options" title="Direct link to Overriding config with CLI options" translate="no">​</a></h3>
<p>All settings in <code>pyproject.toml</code> have corresponding <code>flet build</code> CLI options. If you run the flet build command and specify options that are already configured in <code>pyproject.toml</code>, the CLI option values will override those from the configuration file.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="project-dependencies">Project dependencies<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#project-dependencies" class="hash-link" aria-label="Direct link to Project dependencies" title="Direct link to Project dependencies" translate="no">​</a></h2>
<p>List project dependencies in <code>project.dependencies</code> section. The value is an array with pip-like requirement specifiers:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[project]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">dependencies = [</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  "flet==0.25.0.dev3526",</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  "numpy"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">]</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="product-information">Product information<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#product-information" class="hash-link" aria-label="Direct link to Product information" title="Direct link to Product information" translate="no">​</a></h2>
<p>All Flet specific settings should be put into <code>[tool.flet]</code> section and sub-sections below it.</p>
<p>Product information settings complement the ones in <code>[project]</code> section and allows configuring app bundle identifier and product display name.</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">org = "com.mycompany" # --org</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">product = "Product name" # --product</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">company = "My Company" # --company</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">copyright = "Copyright (C) 2024 by MyCompany" # --copyright</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">build_number = 1 # --build-number</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="app-package-contents">App package contents<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#app-package-contents" class="hash-link" aria-label="Direct link to App package contents" title="Direct link to App package contents" translate="no">​</a></h2>
<p>The following settings control the contents of Python app archive and compilation of app/packages sources.</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">app.module = "main" # --module-name</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">app.path = "src" # path to Python app relative to `pyproject.toml`</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">app.exclude = ["assets"] # --exclude</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">compile.app = false # --compile-app</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">compile.packages = false # --compile-packages</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">compile.cleanup = false # --cleanup-on-compile</span><br></span></code></pre></div></div>
<p>They could be alternatively written under their own sub-sections as:</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.app]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">module = "main"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">path = "src"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">exclude = ["assets"]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.compile]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">app = false</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">packages = false</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">cleanup = false</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="splash">Splash<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#splash" class="hash-link" aria-label="Direct link to Splash" title="Direct link to Splash" translate="no">​</a></h2>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.splash]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">color = "" # --splash-color</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">dark_color = "" # --splash-dark-color</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">web = false # --no-web-splash</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ios = false # --no-ios-splash</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">android = false # --no-android-splash</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="permissions">Permissions<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#permissions" class="hash-link" aria-label="Direct link to Permissions" title="Direct link to Permissions" translate="no">​</a></h2>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">permissions = ["camera", "microphone"] # --permissions</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="deep-linking">Deep linking<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#deep-linking" class="hash-link" aria-label="Direct link to Deep linking" title="Direct link to Deep linking" translate="no">​</a></h2>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.deep_linking]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">scheme = "https" # --deep-linking-scheme</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">host = "mydomain.com" # --deep-linking-host</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="android-settings">Android settings<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#android-settings" class="hash-link" aria-label="Direct link to Android settings" title="Direct link to Android settings" translate="no">​</a></h3>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.android]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">adaptive_icon_background = "" # --android-adaptive-icon-background</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">split_per_abi = false # --split-per-abi</span><br></span></code></pre></div></div>
<p>Permissions (notice quotes <code>"</code> around key names):</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.android.permission] # --android-permissions</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"android.permission.CAMERA" = true</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"android.permission.CAMERA" = true</span><br></span></code></pre></div></div>
<p>Features (notice quotes <code>"</code> around key names):</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.android.feature] # --android-features</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"android.hardware.camera" = false</span><br></span></code></pre></div></div>
<p>Android-specific deep-linking:</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.android.deep_linking]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">scheme = "https" # --deep-linking-scheme</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">host = "mydomain.com" # --deep-linking-host</span><br></span></code></pre></div></div>
<p>Android bundle signing options:</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.android.signing]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># store and key passwords can be passed with `--android-signing-key-store-password`</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># and `--android-signing-key-password` options or</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># FLET_ANDROID_SIGNING_KEY_STORE_PASSWORD</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># and FLET_ANDROID_SIGNING_KEY_PASSWORD environment variables.</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">key_store = "path/to/store.jks" # --android-signing-key-store</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">key_alias = "upload"</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="ios-settings">iOS settings<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#ios-settings" class="hash-link" aria-label="Direct link to iOS settings" title="Direct link to iOS settings" translate="no">​</a></h3>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.ios]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">team = "team_id" # --team</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.ios.info] # --info-plist</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">NSCameraUsageDescription = "This app uses the camera to ..."</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.ios.info.deep_linking]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">scheme = "https"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">host = "mydomain.com"</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="macos-settings">macOS settings<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#macos-settings" class="hash-link" aria-label="Direct link to macOS settings" title="Direct link to macOS settings" translate="no">​</a></h3>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.macos]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">entitlement."com.apple.security.personal-information.photos-library" = true</span><br></span></code></pre></div></div>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">build_arch = "arm64" # --arch - if arch is not specified Flet will build universal package for both arm64 and x86_64 archs</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="web-settings">Web settings<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#web-settings" class="hash-link" aria-label="Direct link to Web settings" title="Direct link to Web settings" translate="no">​</a></h3>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.web]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">base_url = "/" # --base-url</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">renderer = "canvaskit" # --web-renderer</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">use_color_emoji = false # --use-color-emoji</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">route_url_strategy = "path" # --route-url-strategy</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="flutter-settings">Flutter settings<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#flutter-settings" class="hash-link" aria-label="Direct link to Flutter settings" title="Direct link to Flutter settings" translate="no">​</a></h2>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="dependencies">Dependencies<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#dependencies" class="hash-link" aria-label="Direct link to Dependencies" title="Direct link to Dependencies" translate="no">​</a></h3>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flutter.dependencies = ["flet_video", "flet_audio"] # --include-packages</span><br></span></code></pre></div></div>
<p>or with alternative syntax with versions:</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.flutter.dependencies]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">flet_video = "1.0.0"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">flet_audio = "2.0.0"</span><br></span></code></pre></div></div>
<p>or with path to the package on your disk:</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.flutter.dependencies.my_package]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">path = "/path/to/my_package"</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="extra-build-args">Extra build args<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#extra-build-args" class="hash-link" aria-label="Direct link to Extra build args" title="Direct link to Extra build args" translate="no">​</a></h3>
<p>flutter.build_args = ["--some-flutter-arg"] # --flutter-build-args</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="extra-pubspecyaml-settings">Extra <code>pubspec.yaml</code> settings<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#extra-pubspecyaml-settings" class="hash-link" aria-label="Direct link to extra-pubspecyaml-settings" title="Direct link to extra-pubspecyaml-settings" translate="no">​</a></h3>
<p>Allows injecting arbitrary content into resulting <code>pubspec.yaml</code>, for example:</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.flutter.pubspec.dependency_overrides]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">web = "1.0.0"</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="custom-template">Custom template<a href="https://flet.dev/blog/pyproject-toml-support-for-flet-build-command#custom-template" class="hash-link" aria-label="Direct link to Custom template" title="Direct link to Custom template" translate="no">​</a></h2>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[tool.flet.template]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">path = "gh:some-github/repo" # --template</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">dir = "" # --template-dir</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ref = "" # --template-ref</span><br></span></code></pre></div></div>
<p>That's it! Upgrade to Flet 0.25.0.dev3526, give this new feature and try and let us know what you think!</p>
<p>Cheers!</p>]]></content>
        <author>
            <name>Feodor Fitsner</name>
            <uri>ttps://github.com/FeodorFitsner</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Flet new packaging pre-release]]></title>
        <id>https://flet.dev/blog/flet-new-packaging-pre-release</id>
        <link href="https://flet.dev/blog/flet-new-packaging-pre-release"/>
        <updated>2024-10-10T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flet packaging for iOS and Android has been relying on Kivy and it was super annoying when your app depends on Python binary packages, such as Numpy or Pillow. You needed to compile those packages yourself using Kivy command line tools. It was really frustrating and even hopeless if Kivy didn't have "recipes" for some packages, like Pydantic.]]></summary>
        <content type="html"><![CDATA[<p>Flet packaging for iOS and Android has been relying on Kivy and it was super annoying when your app depends on Python binary packages, such as Numpy or Pillow. You needed to compile those packages yourself using Kivy command line tools. It was really frustrating and even hopeless if Kivy didn't have "recipes" for some packages, like Pydantic.</p>
<p>Kivy no more! We've just published Flet 0.25.0.dev3519 pre-release with the improved <code>flet build</code> command which does not use Kivy! Flet is now using its own Python runtime "meticulously crafted in-house".</p>
<p>Flet packaging implementation for iOS and Androind adheres to strict specifications defined in <a href="https://peps.python.org/pep-0730/" target="_blank" rel="noopener noreferrer" class="">PEP 730</a> (iOS) and <a href="https://peps.python.org/pep-0738/" target="_blank" rel="noopener noreferrer" class="">PEP 738</a> (Android) which were implemented and released in Python 3.13 (and back-ported to Python 3.12). When pypi.org supports wheel tags for iOS and Android and 3rd-party Python package maintainers start uploading their mobile packages Flet will be compatible with them and you'll be able to use them in your Flet app.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="installing-pre-release">Installing pre-release<a href="https://flet.dev/blog/flet-new-packaging-pre-release#installing-pre-release" class="hash-link" aria-label="Direct link to Installing pre-release" title="Direct link to Installing pre-release" translate="no">​</a></h2>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pip install flet==0.25.0.dev3519</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_BuS1"><p>For testing purposes we suggest installing Flet pre-release in a dedicated Python virtual environment.</p></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="building-the-app-with-pre-release">Building the app with pre-release<a href="https://flet.dev/blog/flet-new-packaging-pre-release#building-the-app-with-pre-release" class="hash-link" aria-label="Direct link to Building the app with pre-release" title="Direct link to Building the app with pre-release" translate="no">​</a></h2>
<p>To build your app with <code>flet build</code> command and pre-release version of Flet make sure your <code>requirements.txt</code> either contains exact version specifier:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet==0.25.0.dev3519</span><br></span></code></pre></div></div>
<p>or <code>--pre</code> flag before <code>flet</code> dependency:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">--pre</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">flet</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="python-312">Python 3.12<a href="https://flet.dev/blog/flet-new-packaging-pre-release#python-312" class="hash-link" aria-label="Direct link to Python 3.12" title="Direct link to Python 3.12" translate="no">​</a></h2>
<p>Packaged Flet app runs on Python 3.12.6 runtime for all platforms.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="pre-built-binary-packages">Pre-built binary packages<a href="https://flet.dev/blog/flet-new-packaging-pre-release#pre-built-binary-packages" class="hash-link" aria-label="Direct link to Pre-built binary packages" title="Direct link to Pre-built binary packages" translate="no">​</a></h2>
<p><code>flet build</code> command for iOS and Android is now installing pre-built binary packages from <a href="https://pypi.flet.dev/" target="_blank" rel="noopener noreferrer" class="">https://pypi.flet.dev</a>.</p>
<p>New packages can be built with creating a recipe in <a href="https://github.com/flet-dev/mobile-forge" target="_blank" rel="noopener noreferrer" class="">Mobile Forge</a> project. For now, Flet team is authoring those recipes for you, but when the process is polished and fully-automated you'll be able to send a PR and test the compiled package right away.</p>
<p>If you don't yet see a package at <a href="https://pypi.flet.dev/" target="_blank" rel="noopener noreferrer" class="">https://pypi.flet.dev</a> you can request it in <a href="https://github.com/flet-dev/flet/discussions/categories/packages" target="_blank" rel="noopener noreferrer" class="">Flet discussions - Packages</a>. Please do not request pure Python packages. Go to package's "Download files" section at <a href="https://pypi.org/" target="_blank" rel="noopener noreferrer" class="">https://pypi.org</a> and make sure it contains binary platform-specific wheels.</p>
<p>Packaging behavior was changed too:</p>
<ul>
<li class="">The packaging is not trying to replace <code>flet</code> dependency with <code>flet-runtime</code>, <code>flet-embed</code> or <code>flet-pyodide</code>, but install all dependencies "as is" from <code>requirements.txt</code> or <code>pyproject.toml</code> - thanks to the new Flet packages structure (link).</li>
<li class="">If the binary package for target platform is not found the packaging won't be trying to compile it from source distribution, but will fail instead with a meaningful error.</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="new-packages-structure">New packages structure<a href="https://flet.dev/blog/flet-new-packaging-pre-release#new-packages-structure" class="hash-link" aria-label="Direct link to New packages structure" title="Direct link to New packages structure" translate="no">​</a></h2>
<p>The structure avoids rewriting pip dependencies while installing <code>flet</code> package on various platforms. There was a problem of detecting the correct <code>flet</code> package to install (<code>flet-runtime</code>, <code>flet-embed</code> or<code>flet-pyodide</code>?) if <code>flet</code> was not a direct dependency in user's app.</p>
<p>New Flet packages:</p>
<ul>
<li class=""><code>flet</code> - required for minimal Flet setup, app entry point for various platforms. Installed on all platforms.</li>
<li class=""><code>flet-core</code> - required for minimal Flet setup, core logic and controls. Installed on all platforms.</li>
<li class=""><code>flet-cli</code> - contains Flet CLI commands. Installed on desktop only.</li>
<li class=""><code>flet-desktop</code> - contains pre-built Flet "client" app binary for macOS, Windows and Linux. By default installed on macOS and Windows desktops only.</li>
<li class=""><code>flet-desktop-light</code> - contains a light-weight version (without Audio and Video controls) of Flet "client" for Linux. By default installed on Linux desktops only.</li>
<li class=""><code>flet-web</code> - contains Flet web "client" and FastAPI integration. Installed on desktop only.</li>
</ul>
<p>Other words, packaged Flet app contains only <code>flet</code> and <code>flet-core</code> packages.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="light-client-for-linux">"Light" client for Linux<a href="https://flet.dev/blog/flet-new-packaging-pre-release#light-client-for-linux" class="hash-link" aria-label="Direct link to &quot;Light&quot; client for Linux" title="Direct link to &quot;Light&quot; client for Linux" translate="no">​</a></h3>
<p>A light-weight desktop client, without Audio and Video controls, is not installed on Linux by default. It improves initial user experience as user doesn't need to immediately deal with gstreamer (audio) and mpv (video) dependencies right away and Flet "just works".</p>
<p>Once user got some Flet experience and wants to use Video and Audio controls in their application they can install gstreamer and/or mpv and replace Flet desktop with a full version.</p>
<p>Uninstall "light" Flet client:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pip uninstall flet-desktop-light --yes</span><br></span></code></pre></div></div>
<p>Install full Flet desktop client:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pip install flet-desktop==0.25.0.dev3519</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="permissions">Permissions<a href="https://flet.dev/blog/flet-new-packaging-pre-release#permissions" class="hash-link" aria-label="Direct link to Permissions" title="Direct link to Permissions" translate="no">​</a></h2>
<p>New <code>flet build</code> command allows granular control over permissions, features and entitlements embedded into <code>AndroidManifest.xml</code>, <code>Info.plist</code> and <code>.entitlements</code> files.</p>
<p>No more hard-coded permissions in those files!</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="ios">iOS<a href="https://flet.dev/blog/flet-new-packaging-pre-release#ios" class="hash-link" aria-label="Direct link to iOS" title="Direct link to iOS" translate="no">​</a></h3>
<p>Setting iOS permissions:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet build --info-plist permission_1=True|False|description permission_2=True|False|description ...</span><br></span></code></pre></div></div>
<p>For example:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet build --info-plist NSLocationWhenInUseUsageDescription=This app uses location service when in use.</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="macos">macOS<a href="https://flet.dev/blog/flet-new-packaging-pre-release#macos" class="hash-link" aria-label="Direct link to macOS" title="Direct link to macOS" translate="no">​</a></h3>
<p>Setting macOS entitlements:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet build --macos-entitlements name_1=True|False name_2=True|False ...</span><br></span></code></pre></div></div>
<p>Default macOS entitlements:</p>
<ul>
<li class=""><code>com.apple.security.app-sandbox = False</code></li>
<li class=""><code>com.apple.security.cs.allow-jit = True</code></li>
<li class=""><code>com.apple.security.network.client = True</code></li>
<li class=""><code>com.apple.security.network.server" = True</code></li>
</ul>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="android">Android<a href="https://flet.dev/blog/flet-new-packaging-pre-release#android" class="hash-link" aria-label="Direct link to Android" title="Direct link to Android" translate="no">​</a></h3>
<p>Setting Android permissions and features:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet build --android-permissions permission=True|False ... --android-features feature_name=True|False</span><br></span></code></pre></div></div>
<p>For example:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet build \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    --android-permissions android.permission.READ_EXTERNAL_STORAGE=True \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      android.permission.WRITE_EXTERNAL_STORAGE=True \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    --android-features android.hardware.location.network=False</span><br></span></code></pre></div></div>
<p>Default Android permissions:</p>
<ul>
<li class=""><code>android.permission.INTERNET</code></li>
</ul>
<p>Default permissions can be disabled with <code>--android-permissions</code> option and <code>False</code> value, for example:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet build --android-permissions android.permission.INTERNET=False</span><br></span></code></pre></div></div>
<p>Default Android features:</p>
<ul>
<li class=""><code>android.software.leanback=False</code> (<code>False</code> means it's written in manifest as <code>android:required="false"</code>)</li>
<li class=""><code>android.hardware.touchscreen=False</code></li>
</ul>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="cross-platform-permission-groups">Cross-platform permission groups<a href="https://flet.dev/blog/flet-new-packaging-pre-release#cross-platform-permission-groups" class="hash-link" aria-label="Direct link to Cross-platform permission groups" title="Direct link to Cross-platform permission groups" translate="no">​</a></h3>
<p>There are pre-defined permissions that mapped to <code>Info.plist</code>, <code>*.entitlements</code> and <code>AndroidManifest.xml</code> for respective platforms.</p>
<p>Setting cross-platform permissions:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flet build --permissions permission_1 permission_2 ...</span><br></span></code></pre></div></div>
<p>Supported permissions:</p>
<ul>
<li class=""><code>location</code></li>
<li class=""><code>camera</code></li>
<li class=""><code>microphone</code></li>
<li class=""><code>photo_library</code></li>
</ul>
<h4 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="ios-mapping-to-infoplist-entries">iOS mapping to <code>Info.plist</code> entries<a href="https://flet.dev/blog/flet-new-packaging-pre-release#ios-mapping-to-infoplist-entries" class="hash-link" aria-label="Direct link to ios-mapping-to-infoplist-entries" title="Direct link to ios-mapping-to-infoplist-entries" translate="no">​</a></h4>
<ul>
<li class=""><code>location</code>
<ul>
<li class=""><code>NSLocationWhenInUseUsageDescription = This app uses location service when in use.</code></li>
<li class=""><code>NSLocationAlwaysAndWhenInUseUsageDescription = This app uses location service.</code></li>
</ul>
</li>
<li class=""><code>camera</code>
<ul>
<li class=""><code>NSCameraUsageDescription = This app uses the camera to capture photos and videos.</code></li>
</ul>
</li>
<li class=""><code>microphone</code>
<ul>
<li class=""><code>NSMicrophoneUsageDescription = This app uses microphone to record sounds.</code></li>
</ul>
</li>
<li class=""><code>photo_library</code>
<ul>
<li class=""><code>NSPhotoLibraryUsageDescription = This app saves photos and videos to the photo library.</code></li>
</ul>
</li>
</ul>
<h4 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="macos-mapping-to-entitlements">macOS mapping to entitlements<a href="https://flet.dev/blog/flet-new-packaging-pre-release#macos-mapping-to-entitlements" class="hash-link" aria-label="Direct link to macOS mapping to entitlements" title="Direct link to macOS mapping to entitlements" translate="no">​</a></h4>
<ul>
<li class=""><code>location</code>
<ul>
<li class=""><code>com.apple.security.personal-information.location = True</code></li>
</ul>
</li>
<li class=""><code>camera</code>
<ul>
<li class=""><code>com.apple.security.device.camera = True</code></li>
</ul>
</li>
<li class=""><code>microphone</code>
<ul>
<li class=""><code>com.apple.security.device.audio-input = True</code></li>
</ul>
</li>
<li class=""><code>photo_library</code>
<ul>
<li class=""><code>com.apple.security.personal-information.photos-library = True</code></li>
</ul>
</li>
</ul>
<h4 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="android-mappings">Android mappings<a href="https://flet.dev/blog/flet-new-packaging-pre-release#android-mappings" class="hash-link" aria-label="Direct link to Android mappings" title="Direct link to Android mappings" translate="no">​</a></h4>
<ul>
<li class=""><code>location</code>
<ul>
<li class="">permissions:<!-- -->
<ul>
<li class=""><code>android.permission.ACCESS_FINE_LOCATION": True</code></li>
<li class=""><code>android.permission.ACCESS_COARSE_LOCATION": True</code></li>
<li class=""><code>android.permission.ACCESS_BACKGROUND_LOCATION": True</code></li>
</ul>
</li>
<li class="">features:<!-- -->
<ul>
<li class=""><code>android.hardware.location.network": False</code></li>
<li class=""><code>android.hardware.location.gps": False</code></li>
</ul>
</li>
</ul>
</li>
<li class=""><code>camera</code>
<ul>
<li class="">permissions:<!-- -->
<ul>
<li class=""><code>android.permission.CAMERA": True</code></li>
</ul>
</li>
<li class="">features:<!-- -->
<ul>
<li class=""><code>android.hardware.camera": False</code></li>
<li class=""><code>android.hardware.camera.any": False</code></li>
<li class=""><code>android.hardware.camera.front": False</code></li>
<li class=""><code>android.hardware.camera.external": False</code></li>
<li class=""><code>android.hardware.camera.autofocus": False</code></li>
</ul>
</li>
</ul>
</li>
<li class=""><code>microphone</code>
<ul>
<li class="">permissions:<!-- -->
<ul>
<li class=""><code>android.permission.RECORD_AUDIO": True</code></li>
<li class=""><code>android.permission.WRITE_EXTERNAL_STORAGE": True</code></li>
<li class=""><code>android.permission.READ_EXTERNAL_STORAGE": True</code></li>
</ul>
</li>
</ul>
</li>
<li class=""><code>photo_library</code>
<ul>
<li class="">permissions:<!-- -->
<ul>
<li class=""><code>android.permission.READ_MEDIA_VISUAL_USER_SELECTED": True</code></li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="control-over-app-compilation-and-cleanup">Control over app compilation and cleanup<a href="https://flet.dev/blog/flet-new-packaging-pre-release#control-over-app-compilation-and-cleanup" class="hash-link" aria-label="Direct link to Control over app compilation and cleanup" title="Direct link to Control over app compilation and cleanup" translate="no">​</a></h2>
<p><code>flet build</code> command is no longer compiling app <code>.py</code> files into <code>.pyc</code> by default which allows you to avoid (defer?) discovery of any syntax errors in your app and complete the packaging.</p>
<p>You can control the compilation and cleanup with the following new options:</p>
<ul>
<li class=""><code>--compile-app</code> - compile app's <code>.py</code> files.</li>
<li class=""><code>--compile-packages</code> - compile installed packages' <code>.py</code> files.</li>
<li class=""><code>--cleanup-on-compile</code> - remove unnecessary files upon successful compilation.</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="signing-android-bundles">Signing Android bundles<a href="https://flet.dev/blog/flet-new-packaging-pre-release#signing-android-bundles" class="hash-link" aria-label="Direct link to Signing Android bundles" title="Direct link to Signing Android bundles" translate="no">​</a></h2>
<p>Added new options for signing Android builds:</p>
<ul>
<li class=""><code>--android-signing-key-store</code> - path to an upload keystore <code>.jks</code> file for Android apps.</li>
<li class=""><code>--android-signing-key-store-password</code> - Android signing store password.</li>
<li class=""><code>--android-signing-key-alias</code> - Android signing key alias. Default is "upload".</li>
<li class=""><code>--android-signing-key-password</code> - Android signing key password.</li>
</ul>
<p>Read <a href="https://docs.flutter.dev/deployment/android#signing-the-app" target="_blank" rel="noopener noreferrer" class="">Build and release an Android app</a> for more information on how to configure upload key for Android builds.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="data-and-temp-directories-for-the-app">"Data" and "Temp" directories for the app<a href="https://flet.dev/blog/flet-new-packaging-pre-release#data-and-temp-directories-for-the-app" class="hash-link" aria-label="Direct link to &quot;Data&quot; and &quot;Temp&quot; directories for the app" title="Direct link to &quot;Data&quot; and &quot;Temp&quot; directories for the app" translate="no">​</a></h2>
<p>Flet developers have been asking where to store application data, such as uploaded files, SQLite databases, etc. that are persistent across application updates.</p>
<p>This release introduce two environment variables that are available in your Flet apps:</p>
<ul>
<li class=""><code>FLET_APP_STORAGE_DATA</code> - directory for storing application data that is preserved between app updates. That directory is already pre-created.</li>
<li class=""><code>FLET_APP_STORAGE_TEMP</code> - directory for temporary application files, i.e. cache. That directory is already pre-created.</li>
</ul>
<p>For example, data folder path can be read in your app as:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">import os</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># it's `None` when running the app in web mode</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">data_dir = os.getenv("FLET_APP_STORAGE_DATA")</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_BuS1"><p><code>flet run</code> command creates data and temp directories and sets <code>FLET_APP_STORAGE_DATA</code> and <code>FLET_APP_STORAGE_TEMP</code> to their paths.</p></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="deep-linking-configuration">Deep linking configuration<a href="https://flet.dev/blog/flet-new-packaging-pre-release#deep-linking-configuration" class="hash-link" aria-label="Direct link to Deep linking configuration" title="Direct link to Deep linking configuration" translate="no">​</a></h2>
<p>There is a new <code>--deep-linking-url</code> option to configure deep linking for iOS and Android builds. The value must be in the format <code>&lt;sheme&gt;://&lt;host&gt;</code>.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="faster-re-builds">Faster re-builds<a href="https://flet.dev/blog/flet-new-packaging-pre-release#faster-re-builds" class="hash-link" aria-label="Direct link to Faster re-builds" title="Direct link to Faster re-builds" translate="no">​</a></h2>
<p>Ephemeral Flutter app created by <code>flet build</code> command is not re-created all the time in a temp directory, but cached in <code>build/flutter</code> directory which gives faster re-builds, improves packaging troubleshooting and does not pollute temp directory.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="split-apks-per-abi">Split APKs per ABI<a href="https://flet.dev/blog/flet-new-packaging-pre-release#split-apks-per-abi" class="hash-link" aria-label="Direct link to Split APKs per ABI" title="Direct link to Split APKs per ABI" translate="no">​</a></h2>
<p><code>flet build</code> now provides the built-in <code>--split-per-abi</code> option to split the APKs per ABIs.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="known-pre-release-issues">Known pre-release issues<a href="https://flet.dev/blog/flet-new-packaging-pre-release#known-pre-release-issues" class="hash-link" aria-label="Direct link to Known pre-release issues" title="Direct link to Known pre-release issues" translate="no">​</a></h2>
<ul>
<li class=""><code>flet publish</code> is not yet working.</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="what-else-coming-in-the-release">What else coming in the release<a href="https://flet.dev/blog/flet-new-packaging-pre-release#what-else-coming-in-the-release" class="hash-link" aria-label="Direct link to What else coming in the release" title="Direct link to What else coming in the release" translate="no">​</a></h2>
<p>We would like to include a few more things into Flet 0.25.0 release. Expect more pre-releases in the coming weeks.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="pyprojecttoml-support"><code>pyproject.toml</code> support<a href="https://flet.dev/blog/flet-new-packaging-pre-release#pyprojecttoml-support" class="hash-link" aria-label="Direct link to pyprojecttoml-support" title="Direct link to pyprojecttoml-support" translate="no">​</a></h3>
<p>It's inconvenient and bulky to carry all <code>flet build</code> settings as command line options.</p>
<p>You will be able to store project and build settings in <code>[tool.flet]</code> section of <code>pyproject.toml</code>.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="running-flet-app-on-simulator">Running Flet app on simulator<a href="https://flet.dev/blog/flet-new-packaging-pre-release#running-flet-app-on-simulator" class="hash-link" aria-label="Direct link to Running Flet app on simulator" title="Direct link to Running Flet app on simulator" translate="no">​</a></h3>
<p>We will add an option to <code>flet build</code> and run packaged app on a real device or simulator.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="installing-flutter">Installing Flutter<a href="https://flet.dev/blog/flet-new-packaging-pre-release#installing-flutter" class="hash-link" aria-label="Direct link to Installing Flutter" title="Direct link to Installing Flutter" translate="no">​</a></h3>
<p><code>flet build</code> will download and configure Flutter for you if there is no suitable installation available on your machine.</p>]]></content>
        <author>
            <name>Feodor Fitsner</name>
            <uri>ttps://github.com/FeodorFitsner</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Flet v0.24.0 Release Announcement]]></title>
        <id>https://flet.dev/blog/flet-v-0-24-release-announcement</id>
        <link href="https://flet.dev/blog/flet-v-0-24-release-announcement"/>
        <updated>2024-08-31T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[I am very happy to announce the release of Flet version 0.24.0!]]></summary>
        <content type="html"><![CDATA[<p>I am very happy to announce the release of Flet version 0.24.0!
It comes with a very long list of bug fixes, several enhancements and new features.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="new-controls">New Controls<a href="https://flet.dev/blog/flet-v-0-24-release-announcement#new-controls" class="hash-link" aria-label="Direct link to New Controls" title="Direct link to New Controls" translate="no">​</a></h2>
<ul>
<li class=""><a href="https://flet.dev/docs/controls/interactiveviewer/" target="_blank" rel="noopener noreferrer" class=""><code>InteractiveViewer</code></a></li>
<li class=""><a href="https://flet.dev/docs/controls/placeholder/" target="_blank" rel="noopener noreferrer" class=""><code>Placeholder</code></a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="new-properties">New Properties<a href="https://flet.dev/blog/flet-v-0-24-release-announcement#new-properties" class="hash-link" aria-label="Direct link to New Properties" title="Direct link to New Properties" translate="no">​</a></h2>
<ul>
<li class=""><a href="https://flet.dev/docs/audio_recorder/" target="_blank" rel="noopener noreferrer" class=""><code>AudioRecorder</code></a>: <code>cancel_recording()</code></li>
<li class=""><a href="https://flet.dev/docs/video/" target="_blank" rel="noopener noreferrer" class=""><code>Video</code></a>: <code>on_completed</code>, <code>on_track_changed</code></li>
<li class=""><a href="https://flet.dev/docs/types/inputfilter/" target="_blank" rel="noopener noreferrer" class=""><code>InputFilter</code></a>: <code>unicode</code>, <code>case_sensitive</code>, <code>dot_all</code>, <code>multiline</code></li>
<li class=""><a href="https://flet.dev/docs/geolocator/" target="_blank" rel="noopener noreferrer" class=""><code>Geolocator</code></a>: <code>on_error</code>, <code>on_position_change</code></li>
<li class=""><a href="https://flet.dev/docs/charts/bar_chart/" target="_blank" rel="noopener noreferrer" class=""><code>Barchart</code></a>, <a href="https://flet.dev/docs/charts/line_chart/" target="_blank" rel="noopener noreferrer" class=""><code>LineChart</code></a>: <code>tooltip_border_side</code>, <code>tooltip_direction</code>, <code>tooltip_fit_inside_horizontally</code>, <code>tooltip_fit_inside_vertically</code>, <code>tooltip_horizontal_offset</code>, <code>tooltip_margin</code>, <code>tooltip_max_content_width</code>, <code>tooltip_padding</code>, <code>tooltip_rounded_radius</code>, <code>tooltip_rotate_angle</code></li>
<li class=""><a href="https://flet.dev/docs/controls/container/" target="_blank" rel="noopener noreferrer" class=""><code>Container</code></a>: <code>decoration</code>, <code>foreground_decoration</code>, <code>ignore_interactions</code>, <code>image</code></li>
<li class=""><a href="https://flet.dev/docs/controls/page/" target="_blank" rel="noopener noreferrer" class=""><code>Page</code></a>, <a href="https://flet.dev/docs/controls/view/" target="_blank" rel="noopener noreferrer" class=""><code>View</code></a>: <code>decoration</code>, <code>foreground_decoration</code></li>
<li class=""><a href="https://flet.dev/docs/controls/cupertinotextfield/" target="_blank" rel="noopener noreferrer" class=""><code>CupertinoTextField</code></a>: <code>enable_scribble</code>, <code>image</code>, <code>obscuring_character</code>, <code>padding</code>, <code>scroll_padding</code>, <code>on_click</code></li>
<li class=""><a href="https://flet.dev/docs/controls/datatable/" target="_blank" rel="noopener noreferrer" class=""><code>DataTable</code></a>: <code>heading_row_alignment</code></li>
<li class=""><a href="https://flet.dev/docs/controls/textfield/" target="_blank" rel="noopener noreferrer" class=""><code>TextField</code></a>: <code>counter</code>, <code>disabled_hint_content</code>, <code>options_fill_horizontally</code></li>
<li class=""><a href="https://flet.dev/docs/controls/expansiontile/" target="_blank" rel="noopener noreferrer" class=""><code>ExpansionTile</code></a>: <code>min_tile_height</code>, <code>show_trailing_icon</code></li>
<li class=""><a href="https://flet.dev/docs/controls/markdown/" target="_blank" rel="noopener noreferrer" class=""><code>Markdown</code></a>: <code>fit_content</code>, <code>img_error_content</code>, <code>md_style_sheet</code>, <code>shrink_wrap</code>, <code>soft_line_break</code>, <code>on_selection_change</code></li>
<li class=""><a href="https://flet.dev/docs/controls/menuitembutton/" target="_blank" rel="noopener noreferrer" class=""><code>MenuItemButton</code></a>: <code>autofocus</code>, <code>overflow_axis</code>, <code>semantic_label</code></li>
<li class=""><a href="https://flet.dev/docs/controls/tabs/" target="_blank" rel="noopener noreferrer" class=""><code>Tabs</code></a>: <code>label_padding</code>, <code>label_text_style</code>, <code>padding</code>, <code>splash_border_radius</code>, <code>unselected_label_text_style</code>, <code>on_click</code></li>
<li class="">and lot of <a href="https://flet.dev/docs/reference/" target="_blank" rel="noopener noreferrer" class="">new classes</a> (enums, dataclasses, events)…</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="enhancements">Enhancements<a href="https://flet.dev/blog/flet-v-0-24-release-announcement#enhancements" class="hash-link" aria-label="Direct link to Enhancements" title="Direct link to Enhancements" translate="no">​</a></h2>
<ul>
<li class="">Better string output of Events when printed</li>
<li class=""><code>Image.filter_quality</code> now has a default of <code>FilterQuality.MEDIUM</code> (previously <code>FilterQuality.LOW</code>), which is a better default for downscaled images.</li>
<li class=""><code>Geolocator</code> control has been improved to support location streaming through the newly added on_position_change event. When defined, you will be able to "listen" to location changes as they happen.</li>
<li class="">When <code>AppBar.adaptive=True</code> and the app is running on an Apple platform, the <code>AppBar.actions</code> controls are now wrapped in a <code>Row</code>, then displayed. Before this, only the first item of <code>AppBar.actions</code> list was displayed.</li>
<li class="">The <code>Markdown</code> control has been significantly improved. It can now display SVG images and be much more customized.</li>
<li class="">A very requested feature was the ability to set a background image or gradient for the application. In <a href="https://github.com/flet-dev/flet/pull/3820" target="_blank" rel="noopener noreferrer" class="">#3820</a>, we made this possible and easy to use.</li>
<li class="">rtl (right-to-left) property has been added to more controls (<code>NavigationRailDestination</code>, <code>NavigationRail</code>, <code>AppBar</code>, <code>CupertinoAppBar</code>, and <code>NavigationDrawer</code> ) to improve support for right-to-left text directions.</li>
<li class="">Introduced <code>--no-rich-output</code> flag (only in <code>flet build</code> command for now) to make it possible to disable rich output (mainly emojis) in the console. More information in <a href="https://github.com/flet-dev/flet/pull/3708" target="_blank" rel="noopener noreferrer" class="">#3708</a>.</li>
<li class="">Typing has been significantly improved, particularly for event-handler properties. In modern IDEs like PyCharm and VSCode, you can now easily determine the type of an event handler's argument by simply hovering over the event in the control. Additionally, the IDE will highlight errors when you attempt to access a non-existent property on the event handler argument, ensuring more robust and error-free code.</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="bug-fixes">Bug Fixes<a href="https://flet.dev/blog/flet-v-0-24-release-announcement#bug-fixes" class="hash-link" aria-label="Direct link to Bug Fixes" title="Direct link to Bug Fixes" translate="no">​</a></h2>
<p>The below issues were successfully fixed:</p>
<ul>
<li class=""><a href="https://github.com/flet-dev/flet/issues/3769" target="_blank" rel="noopener noreferrer" class="">#3769</a>: <code>InputFilter</code> clears the <code>TextField</code> text content when an invalid character is entered</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/3770" target="_blank" rel="noopener noreferrer" class="">#3770</a>: <code>Theme.floating_action_button_theme</code> non existent</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/3734" target="_blank" rel="noopener noreferrer" class="">#3734</a>: Ensure <code>Dropdown.alignment</code> is respected.</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/3730" target="_blank" rel="noopener noreferrer" class="">#3730</a>: <code>UnicodeEncodeError</code> raised when packaging on WindowOS</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/2160" target="_blank" rel="noopener noreferrer" class="">#2160</a>: <code>Markdown</code> control can't render svg images</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/2158" target="_blank" rel="noopener noreferrer" class="">#2158</a>: <code>Markdown</code> broken when an image is not found</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/3679" target="_blank" rel="noopener noreferrer" class="">#3679</a>: Broken <code>Dismissible</code></li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/3670" target="_blank" rel="noopener noreferrer" class="">#3670</a>: <code>Switch.height</code> and <code>Switch.width</code> not respected</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/3612" target="_blank" rel="noopener noreferrer" class="">#3612</a>, <a href="https://github.com/flet-dev/flet/issues/3566" target="_blank" rel="noopener noreferrer" class="">#3566</a>: Broken <code>OnScrollEvent</code></li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/3564" target="_blank" rel="noopener noreferrer" class="">#3564</a>: Broken <code>TextField.capitalization</code></li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/3649" target="_blank" rel="noopener noreferrer" class="">#3649</a>: <code>CupertinoPicker</code> jumps-scroll on some platforms</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/3557" target="_blank" rel="noopener noreferrer" class="">#3557</a>: Impeller causes blank screen on mac Intel</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/3574" target="_blank" rel="noopener noreferrer" class="">#3574</a>: <code>Geolocator</code> not working on Android devices</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/3505" target="_blank" rel="noopener noreferrer" class="">#3505</a>: <code>WindowEventType</code> doesn't contain fullscreen all events</li>
</ul>
<p>Thanks to all those who reported them!</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="deprecations">Deprecations<a href="https://flet.dev/blog/flet-v-0-24-release-announcement#deprecations" class="hash-link" aria-label="Direct link to Deprecations" title="Direct link to Deprecations" translate="no">​</a></h2>
<p>All deprecated items from this release will be removed in version 0.27.0.</p>
<ul>
<li class=""><code>ThemeVisualDensity</code> is deprecated and has been renamed to <a href="https://flet.dev/docs/types/visualdensity/" target="_blank" rel="noopener noreferrer" class=""><code>VisualDensity</code></a></li>
<li class=""><a href="https://flet.dev/docs/controls/cupertinobutton/" target="_blank" rel="noopener noreferrer" class=""><code>CupertinoButton</code></a>: <code>disabled_color</code> is deprecated and has been renamed to <code>disabled_bgcolor</code>, which better reflects its use</li>
<li class=""><a href="https://flet.dev/docs/controls/markdown/" target="_blank" rel="noopener noreferrer" class=""><code>Markdown</code></a>: <code>code_style</code> is deprecated and should now be accessed as  <code>code_style_sheet.code_text_style</code></li>
<li class=""><a href="https://flet.dev/docs/controls/container/" target="_blank" rel="noopener noreferrer" class=""><code>Container</code></a>: <code>image_fit</code>, <code>image_opacity</code>, <code>image_repeat</code>, <code>image_src</code> and <code>image_src_base64</code> are deprecated and should now be accessed from <code>image</code> which is of type <a href="https://flet.dev/docs/types/decorationimage/" target="_blank" rel="noopener noreferrer" class=""><code>DecorationImage</code></a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="breaking-changes-and-migration">Breaking Changes and Migration<a href="https://flet.dev/blog/flet-v-0-24-release-announcement#breaking-changes-and-migration" class="hash-link" aria-label="Direct link to Breaking Changes and Migration" title="Direct link to Breaking Changes and Migration" translate="no">​</a></h2>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="tooltip">Tooltip<a href="https://flet.dev/blog/flet-v-0-24-release-announcement#tooltip" class="hash-link" aria-label="Direct link to Tooltip" title="Direct link to Tooltip" translate="no">​</a></h3>
<p>The Tooltip class is no more a Flet control and is from now on a simple Python dataclass. The tooltip property (available in almost all controls) now supports both strings and Tooltip objects.</p>
<p>Below is how to migrate:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># before</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Tooltip</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        message</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"This is tooltip"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        content</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hover to see tooltip"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        padding</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        border_radius</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># after</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"Hover to see tooltip"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        tooltip</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Tooltip</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            message</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"This is tooltip"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            padding</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            border_radius</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="textfield-inputfilter">TextField InputFilter<a href="https://flet.dev/blog/flet-v-0-24-release-announcement#textfield-inputfilter" class="hash-link" aria-label="Direct link to TextField InputFilter" title="Direct link to TextField InputFilter" translate="no">​</a></h3>
<p>We modified how <code>InputFilter.regex_string</code> is internally handled. As a result of this, you (might) now have to anchor your regex pattern. This simply implies using start (^) and end ($) regex anchors.
For example: <code>r"[0-9]"</code> now becomes <code>r"^[0-9]$"</code>. Using this new string will lead work as expected and only numbers/digits will be allowed, but you might notice another issue: the last character of the text field cannot be deleted. To resolve this, you need to add an asterisk (*) in the regex which in this case will simply mean "match zero or more digits (including an empty string)". The new regex now becomes <code>r"^[0-9]*$"</code>.
To ease this migration, you can use an AI tool with the following simple prompt: <code>"update the following regex pattern: #### ensuring that the entire string matches the pattern and it allows for an empty string"</code>.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="event-handler-subscription">Event-Handler subscription<a href="https://flet.dev/blog/flet-v-0-24-release-announcement#event-handler-subscription" class="hash-link" aria-label="Direct link to Event-Handler subscription" title="Direct link to Event-Handler subscription" translate="no">​</a></h3>
<p>The possibility to "subscribe" more than one callback to an event handler has been removed, as this was somehow biased (was only possible on some, and not all).
Below is a simple example:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Page</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">print_one</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"1"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">print_two</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"2"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">print_three</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"3"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    c </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Container</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        bgcolor</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Colors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">random_color</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">300</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        height</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">300</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># subscribe callbacks</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">on_tap_down </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> print_one</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">on_tap_down </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> print_two</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">on_tap_down </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> print_three</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>In the above code, we subscribe multiple callbacks to the <a href="https://flet.dev/docs/controls/container/#flet.Container.on_tap_down" target="_blank" rel="noopener noreferrer" class=""><code>Container.on_tap_down</code></a> event. Prior to Flet version 0.24.0, running this code and tapping on the <code>Container</code>, you will see all the callbacks getting called ("1", "2" and "3" are printed out).
From Flet version 0.24.0 going forward, one event = one callback. Meaning only the lastly subscribed callback will get executed ("3" is printed out)
So, if you still want the final output to resemble the first one you can simply create one callback which calls the others:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Page</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">#....</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">print_all</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            print_one</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            print_two</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            print_three</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    c </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Container</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            bgcolor</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Colors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">random_color</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">300</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            height</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">300</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            on_tap_down</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">print_all</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># OR</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">on_tap_down </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> print_all</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="conclusion">Conclusion<a href="https://flet.dev/blog/flet-v-0-24-release-announcement#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>As you can see, we made a lot of changes in this release and as usual, your feedback is highly welcomed!</p>
<p>Upgrade to Flet 0.24.0, test your apps and let us know how you find the new features we added.
If you have any questions, please join <a href="https://discord.gg/dzWXP8SHG8" target="_blank" rel="noopener noreferrer" class="">Flet Discord server</a> or create a new thread
on <a href="https://github.com/flet-dev/flet/discussions" target="_blank" rel="noopener noreferrer" class="">Flet GitHub discussions</a>.</p>
<p>Happy Flet-ing! 👾</p>]]></content>
        <author>
            <name>Henri Ndonko</name>
            <uri>https://github.com/ndonkoHenri</uri>
        </author>
        <category label="releases" term="releases"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Flet v0.23.0 Release Announcement]]></title>
        <id>https://flet.dev/blog/flet-v-0-23-release-announcement</id>
        <link href="https://flet.dev/blog/flet-v-0-23-release-announcement"/>
        <updated>2024-06-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We are excited to announce the release of Flet 0.23.0. It is a big release with many new features and bug fixes.]]></summary>
        <content type="html"><![CDATA[<p>We are excited to announce the release of Flet 0.23.0. It is a big release with many new features and bug fixes.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="new-controls">New Controls<a href="https://flet.dev/blog/flet-v-0-23-release-announcement#new-controls" class="hash-link" aria-label="Direct link to New Controls" title="Direct link to New Controls" translate="no">​</a></h2>
<ul>
<li class=""><a href="https://flet.dev/docs/controls/autocomplete/" target="_blank" rel="noopener noreferrer" class=""><code>AutoComplete</code></a></li>
<li class=""><a href="https://flet.dev/docs/controls/autofillgroup/" target="_blank" rel="noopener noreferrer" class=""><code>AutoFillGroup</code></a></li>
<li class=""><a href="https://flet.dev/docs/flashlight/" target="_blank" rel="noopener noreferrer" class=""><code>Flashlight</code></a></li>
<li class=""><a href="https://flet.dev/docs/geolocator/" target="_blank" rel="noopener noreferrer" class=""><code>Geolocator</code></a></li>
<li class=""><a href="https://flet.dev/docs/map/" target="_blank" rel="noopener noreferrer" class=""><code>Map</code></a></li>
<li class=""><a href="https://flet.dev/docs/permission_handler/" target="_blank" rel="noopener noreferrer" class=""><code>PermissionHandler</code></a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="new-properties">New Properties<a href="https://flet.dev/blog/flet-v-0-23-release-announcement#new-properties" class="hash-link" aria-label="Direct link to New Properties" title="Direct link to New Properties" translate="no">​</a></h2>
<ul>
<li class=""><a href="https://flet.dev/docs/controls/dropdownoption/#flet.DropdownOption" target="_blank" rel="noopener noreferrer" class=""><code>Option</code></a>: <code>content</code>, <code>text_style</code></li>
<li class=""><a href="https://flet.dev/docs/types/textstyle/" target="_blank" rel="noopener noreferrer" class=""><code>TextStyle</code></a>: <code>baseline</code>, <code>overflow</code>, <code>word_spacing</code></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="error-handling">Error Handling<a href="https://flet.dev/blog/flet-v-0-23-release-announcement#error-handling" class="hash-link" aria-label="Direct link to Error Handling" title="Direct link to Error Handling" translate="no">​</a></h2>
<blockquote>
<p>PEP 20 (Zen of Python): Errors should never pass silently.</p>
</blockquote>
<p>Several devs reported that, on some occasions, a control might visually break without clear information on what caused
the break.</p>
<p>For example, in issue <a href="https://github.com/flet-dev/flet/issues/3149" target="_blank" rel="noopener noreferrer" class="">#3149</a>, @base-13 mentioned that <em>"in a DataTable if
the number of columns is less than the number of datacells in any row it will grey out whole table without throwing
error"</em>.</p>
<p>Knowing this, we added more assertion-checks in most of the controls, such that, when you provide them with a wrong
value, an AssertionError is raised with a very clear message of what was wrongly done.</p>
<p>If you find out that some checks are still missing, please point them out so they can be addressed.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="command-line-cli-output">Command Line (CLI) Output<a href="https://flet.dev/blog/flet-v-0-23-release-announcement#command-line-cli-output" class="hash-link" aria-label="Direct link to Command Line (CLI) Output" title="Direct link to Command Line (CLI) Output" translate="no">​</a></h2>
<p>The output of the <code>flet build</code> command has been prettified.</p>
<p>Also, a new option has been added --show-platform-matrix which displays a table containing the build platform matrix,
which has header columns "Command" (possible build commands) and "Platform" (the device you should use with the
respective command).</p>
<p>Furthermore, when the targeted platform can't be built on your device, a table displaying the build platform matrix is
shown with an informative message.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="breaking-changes">Breaking Changes<a href="https://flet.dev/blog/flet-v-0-23-release-announcement#breaking-changes" class="hash-link" aria-label="Direct link to Breaking Changes" title="Direct link to Breaking Changes" translate="no">​</a></h2>
<p>While doing "Error Handling" mentioned above, we had to mark some important properties as required.</p>
<p>The following properties are now "required" (must be provided and visible) when creating an instance of their classes:</p>
<ul>
<li class=""><a href="https://flet.dev/docs/controls/animatedswitcher/#flet.AnimatedSwitcher.content" target="_blank" rel="noopener noreferrer" class=""><code>AnimatedSwitcher.content</code></a></li>
<li class=""><a href="https://flet.dev/docs/controls/banner/#flet.Banner.content" target="_blank" rel="noopener noreferrer" class=""><code>Banner.content</code></a>, <a href="https://flet.dev/docs/controls/banner/#flet.Banner.actions" target="_blank" rel="noopener noreferrer" class=""><code>Banner.actions</code></a></li>
<li class=""><a href="https://flet.dev/docs/controls/bottomsheet/#flet.BottomSheet.content" target="_blank" rel="noopener noreferrer" class=""><code>BottomSheet.content</code></a></li>
<li class=""><a href="https://flet.dev/docs/controls/cupertinoactionsheetaction/#flet.CupertinoActionSheetAction.content" target="_blank" rel="noopener noreferrer" class=""><code>CupertinoActionSheetAction.content</code></a></li>
<li class=""><a href="https://flet.dev/docs/controls/datatable/" target="_blank" rel="noopener noreferrer" class=""><code>DataRow.cells</code></a></li>
<li class=""><a href="https://flet.dev/docs/controls/datatable/" target="_blank" rel="noopener noreferrer" class=""><code>DataTable.columns</code></a></li>
<li class=""><a href="https://flet.dev/docs/controls/dragtarget/#flet.DragTarget.content" target="_blank" rel="noopener noreferrer" class=""><code>DragTarget.content</code></a></li>
<li class=""><a href="https://flet.dev/docs/controls/draggable/#flet.Draggable.content" target="_blank" rel="noopener noreferrer" class=""><code>Draggable.content</code></a></li>
<li class=""><a href="https://flet.dev/docs/controls/expansiontile/#flet.ExpansionTile.title" target="_blank" rel="noopener noreferrer" class=""><code>ExpansionTile.title</code></a></li>
<li class=""><a href="https://flet.dev/docs/controls/menubar/#flet.MenuBar.controls" target="_blank" rel="noopener noreferrer" class=""><code>MenuBar.controls</code></a></li>
<li class=""><a href="https://flet.dev/docs/controls/pagelet/#flet.Pagelet.content" target="_blank" rel="noopener noreferrer" class=""><code>Pagelet.content</code></a></li>
<li class=""><a href="https://flet.dev/docs/controls/radio/#flet.Radio.content" target="_blank" rel="noopener noreferrer" class=""><code>RadioGroup.content</code></a></li>
<li class=""><a href="https://flet.dev/docs/controls/safearea/#flet.SafeArea.content" target="_blank" rel="noopener noreferrer" class=""><code>SafeArea.content</code></a></li>
<li class=""><a href="https://flet.dev/docs/controls/shadermask/#flet.ShaderMask.shader" target="_blank" rel="noopener noreferrer" class=""><code>ShaderMask.shader</code></a></li>
<li class=""><a href="https://flet.dev/docs/controls/windowdragarea/#flet.WindowDragArea.content" target="_blank" rel="noopener noreferrer" class=""><code>WindowDragArea.content</code></a></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="bug-fixes">Bug Fixes<a href="https://flet.dev/blog/flet-v-0-23-release-announcement#bug-fixes" class="hash-link" aria-label="Direct link to Bug Fixes" title="Direct link to Bug Fixes" translate="no">​</a></h2>
<p>The below issues were successfully fixed:</p>
<ul>
<li class=""><a href="https://github.com/flet-dev/flet/issues/3144" target="_blank" rel="noopener noreferrer" class="">#3144</a>: <code>ScrollbarTheme.thickness</code> value not respected when not
interacting with</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/3072" target="_blank" rel="noopener noreferrer" class="">#3072</a>: High-resolution videos play laggy on Android TV devices.</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/3023" target="_blank" rel="noopener noreferrer" class="">#3023</a>: (Regression) Some <code>LineChart</code> colors not visually respected</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/2989" target="_blank" rel="noopener noreferrer" class="">#2989</a>: Color of <a href="https://flet.dev/docs/controls/dropdown/" target="_blank" rel="noopener noreferrer" class=""><code>Dropdown</code></a> when disabled
doesn't reflect its disabled state</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/1753" target="_blank" rel="noopener noreferrer" class="">#1753</a>: <a href="https://flet.dev/docs/controls/markdown/" target="_blank" rel="noopener noreferrer" class=""><code>Markdown</code></a> code block not selectable</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/3097" target="_blank" rel="noopener noreferrer" class="">#3097</a>: Hot-reload occurs when a file is opened</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/1647" target="_blank" rel="noopener noreferrer" class="">#1647</a>: <a href="https://flet.dev/docs/controls/container/#flet.Container.theme_mode" target="_blank" rel="noopener noreferrer" class=""><code>Container.theme_mode</code></a>
not honoured when <code>Container.theme=None</code></li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/3064" target="_blank" rel="noopener noreferrer" class="">#3064</a>: <a href="https://flet.dev/docs/controls/container/#flet.Container.on_tap_down" target="_blank" rel="noopener noreferrer" class=""><code>Container.on_tap_down</code></a>
not called when <code>Container.on_click=None</code></li>
</ul>
<p>Special Thanks to the dynamic Flet community for reporting all the issues they encountered. We keep working hard on
solving the remaining ones.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="deprecations">Deprecations<a href="https://flet.dev/blog/flet-v-0-23-release-announcement#deprecations" class="hash-link" aria-label="Direct link to Deprecations" title="Direct link to Deprecations" translate="no">​</a></h2>
<ul>
<li class="">
<p>All the <code>Page.window_***</code> properties are now deprecated and moved to <a href="https://flet.dev/docs/controls/page/#flet.Page.window" target="_blank" rel="noopener noreferrer" class=""><code>Page.window</code></a>
property, which is of type <a href="https://flet.dev/docs/types/window/" target="_blank" rel="noopener noreferrer" class=""><code>Window</code></a>.
To migrate, simply use change <code>window_</code> to <code>window.</code> as seen below:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># before</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">window_height </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">on_window_event </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">lambda</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">.</span><span class="token builtin">type</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># now</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">window</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">height </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">window</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">on_event </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">lambda</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">.</span><span class="token builtin">type</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
</li>
<li class="">
<p><code>SafeArea.minimum</code> is deprecated and has been renamed
to <a href="https://flet.dev/docs/controls/safearea/#flet.SafeArea.minimum_padding" target="_blank" rel="noopener noreferrer" class=""><code>minimum_padding</code></a></p>
</li>
<li class="">
<p><code>MaterialState</code> enum is deprecated and has been renamed to <a href="https://flet.dev/docs/types/controlstate/" target="_blank" rel="noopener noreferrer" class=""><code>ControlState</code></a></p>
</li>
<li class="">
<p><code>NavigationDestination</code> is deprecated and has been renamed
to <a href="https://flet.dev/docs/controls/navigationbardestination/#flet.NavigationBarDestination" target="_blank" rel="noopener noreferrer" class=""><code>NavigationBarDestination</code></a></p>
</li>
</ul>
<p>Also, the deprecation policy has been modified. While Flet is pre-1.0, all deprecations will be removed from the API after the next 3 releases.
So the above deprecations made in v0.23.0 (and all the other deprecations made in the previous versions), will be removed in v0.26.0.</p>
<p>That's it! :)</p>
<p>Upgrade to Flet 0.23.0, test your apps and let us know how you find the new features we added.
If you have any questions, please join <a href="https://discord.gg/dzWXP8SHG8" target="_blank" rel="noopener noreferrer" class="">Flet Discord server</a> or create a new thread
on <a href="https://github.com/flet-dev/flet/discussions" target="_blank" rel="noopener noreferrer" class="">Flet GitHub discussions</a>.</p>
<p>Happy Flet-ing!</p>]]></content>
        <author>
            <name>Henri Ndonko</name>
            <uri>https://github.com/ndonkoHenri</uri>
        </author>
        <category label="releases" term="releases"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Flet at PyCon US 2024]]></title>
        <id>https://flet.dev/blog/flet-at-pycon-us-2024</id>
        <link href="https://flet.dev/blog/flet-at-pycon-us-2024"/>
        <updated>2024-05-24T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Last week we attended PyCon US in a beautiful city of Pittsburgh, PA!]]></summary>
        <content type="html"><![CDATA[<p>Last week we attended PyCon US in a beautiful city of Pittsburgh, PA!</p>
<p>I've been on many conferences, but at PyCon I was amazed by the spacious venue, flawless event organization, high-quality content and welcoming community 😎, ...and good food 🍔!</p>
<img src="https://flet.dev/img/blog/pycon-us-2024/pycon-us-2024-collage.jpg" class="screenshot-60 screenshot-rounded">
<p>We met a lot of great people and, especially, wonderful people from Beeware (hello Russell, Malcolm and Russell 👋). They did a great job of popularizing Python on mobile and advocating the addition of iOS and Android to the list of supported platforms in the next release of Python 3.13 🎉!</p>
<p>We enjoyed good talks and inspirational key notes, learned new things, enjoyed the city. Lightning talks (short 5-minute presentations) were real fun!</p>
<p>Oh, I saw Guido van Rossum (The Creator of Python himself, in case you didn't know 😅) at Microsoft booth, but didn't have a chance to take a picture with him as there was a line up 😉.</p>
<p>As first time attendees we did't do talks or presentations, but watched and learned instead.
We plan to present next year 🤞.</p>
<p>Next PyCon US is going to be at the same place. Will come again and hope to see more of you there!</p>]]></content>
        <author>
            <name>Feodor Fitsner</name>
            <uri>ttps://github.com/FeodorFitsner</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Flet packaging update]]></title>
        <id>https://flet.dev/blog/flet-packaging-update</id>
        <link href="https://flet.dev/blog/flet-packaging-update"/>
        <updated>2024-05-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The problem]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="the-problem">The problem<a href="https://flet.dev/blog/flet-packaging-update#the-problem" class="hash-link" aria-label="Direct link to The problem" title="Direct link to The problem" translate="no">​</a></h2>
<p>When you package your Flet program in Python to run on a mobile device (or desktop) the resulting
bundle (.apk, .ipa, .exe, .app) contains your Python program, Python interpreter and <a href="https://docs.python.org/3/library/index.html" target="_blank" rel="noopener noreferrer" class="">Python Standard Library</a>.</p>
<p>If your program uses only Python standard library then packaging process is relatively easy - Flet zips your code and combines Flutter app together with Python interpreter and standard library both compiled for the target platform: Android or iOS.</p>
<p>However, problems may arise when your Flet program uses third-party packages, with thousands of them published on PyPI or Conda.</p>
<p>There are two kinds of third-party packages:</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="pure-python-packages">Pure-Python packages<a href="https://flet.dev/blog/flet-packaging-update#pure-python-packages" class="hash-link" aria-label="Direct link to Pure-Python packages" title="Direct link to Pure-Python packages" translate="no">​</a></h3>
<p>A "pure-Python" package is a package that only contains Python code, and doesn't include extensions written in C, C++, Rust or other languages. You only need a Python interpreter and the Python Standard Library to run a pure-Python package, and it doesn't matter what your OS or platform is.</p>
<p>Examples of such packages: <code>httpx</code>, <code>click</code>, <code>rich</code>, <code>requests</code>.</p>
<p>To verify if the package is pure, find that package on <a href="https://pypi.org/" target="_blank" rel="noopener noreferrer" class="">PyPI</a> and navigate to its "Download files" page. If under "Built distribution" section there is only one wheel ending with <code>-py3-none-any.whl</code> then <em>most probably</em> it's a pure Python package that will work "as is" on any device with Python.</p>
<img src="https://flet.dev/img/blog/packaging/pypi-pure-package.png" class="screenshot-80 screenshot-rounded">
<p>We say <em>"probably"</em> because that pure package could depend on a non-pure package which brings you to the next section. For example, <a href="https://pypi.org/project/pydantic/#files" target="_blank" rel="noopener noreferrer" class=""><code>pydantic</code></a> is a pure package, but to work properly it requires <a href="https://pypi.org/project/pydantic-core/#files" target="_blank" rel="noopener noreferrer" class=""><code>pydantic-core</code></a> non-pure package written in Rust.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="non-pure-python-packages">Non-pure Python packages<a href="https://flet.dev/blog/flet-packaging-update#non-pure-python-packages" class="hash-link" aria-label="Direct link to Non-pure Python packages" title="Direct link to Non-pure Python packages" translate="no">​</a></h3>
<p>A "non-pure Python" package is one that is fully or partially written in C, C++, Rust, or another language and must be compiled to machine code for the platform on which it will run.</p>
<p>Examples of such packages: <code>cryptography</code>, <code>opencv-python</code>, <code>numpy</code>, <code>msgpack</code>.</p>
<p>On "Download files" page of non-pure package you will find a bunch of wheels pre-built for various platforms: macOS, Windows, Linux.</p>
<img src="https://flet.dev/img/blog/packaging/pypi-non-pure-package.png" class="screenshot-80 screenshot-rounded">
<p>When you run <code>pip install &lt;package&gt;</code> pip tries to find a wheel for your specific platform and Python version looking at
wheel suffixes that include that information.</p>
<p>It's a courtesy of package developer to provide pre-compiled wheels for multiple platforms. There could be missing wheels for some platforms, or no wheels at all - just <code>.tar.gz</code> under "Source distribution" with package sources.</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="building-package-from-sources-is-hard">Building package from sources is hard<a href="https://flet.dev/blog/flet-packaging-update#building-package-from-sources-is-hard" class="hash-link" aria-label="Direct link to Building package from sources is hard" title="Direct link to Building package from sources is hard" translate="no">​</a></h4>
<p>To install a package with source distribution only, pip will attempt to build non-Python code on your machine using installed compilers, linkers, libraries, and SDKs. However, this process can be lengthy and error-prone. The compiled code base might be large, and your machine could lack the required libraries or toolchains.</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="no-wheels-for-ios-and-android-yet">No wheels for iOS and Android yet<a href="https://flet.dev/blog/flet-packaging-update#no-wheels-for-ios-and-android-yet" class="hash-link" aria-label="Direct link to No wheels for iOS and Android yet" title="Direct link to No wheels for iOS and Android yet" translate="no">​</a></h4>
<p>There are no pre-built wheels for iOS and Android on PyPI and PyPI's validation process won't allow package developers to upload them anyway as both iOS and Android are not officially supported platforms in Python.</p>
<p>There is a process (<a href="https://peps.python.org/pep-0730/" target="_blank" rel="noopener noreferrer" class="">PEP 730</a> and <a href="https://peps.python.org/pep-0738/" target="_blank" rel="noopener noreferrer" class="">PEP 738</a>) to add official support for iOS and Android to Python 3.13, so, hopefully, the developer experience will improve.</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="package-dependencies">Package dependencies<a href="https://flet.dev/blog/flet-packaging-update#package-dependencies" class="hash-link" aria-label="Direct link to Package dependencies" title="Direct link to Package dependencies" translate="no">​</a></h4>
<p>Pure-Python packages can import or depend on non-pure packages and you should keep that in mind while packaging your Flet app to run on a mobile device.</p>
<p>For example, <code>supabase</code> package, to access Supabase API, is a pure package which depends on <code>pydantic</code> package which is also pure Python package. In its turn <code>pydantic</code> package depends on <code>pydantic-core</code> which is a non-pure package written in Rust. Thus, to run your Flet app using Supabase API the packaging process should be able to find a pre-build wheel for your target platform. If PyPI doesn't have that wheel then it could be either Flet developers, building that wheel on their servers and hosting it somewhere, or you, building that wheel on your own machine.</p>
<p>To see a dependency graph for a package you can use <a href="https://pypi.org/project/pipgrip/" target="_blank" rel="noopener noreferrer" class=""><code>pipgrip</code></a>.</p>
<p>Run it with <code>--tree</code> option to get a tree view of dependencies:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">$ pipgrip --tree fastapi</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">fastapi (0.110.3)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">├── pydantic!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,&lt;3.0.0,&gt;=1.7.4 (2.7.1)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│   ├── annotated-types&gt;=0.4.0 (0.6.0)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│   ├── pydantic-core==2.18.2 (2.18.2)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│   │   └── typing-extensions!=4.7.0,&gt;=4.6.0 (4.11.0)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│   └── typing-extensions&gt;=4.6.1 (4.11.0)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">├── starlette&lt;0.38.0,&gt;=0.37.2 (0.37.2)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│   └── anyio&lt;5,&gt;=3.4.0 (4.3.0)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│       ├── idna&gt;=2.8 (3.7)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">│       └── sniffio&gt;=1.1 (1.3.1)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">└── typing-extensions&gt;=4.8.0 (4.11.0)</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="current-approach">Current approach<a href="https://flet.dev/blog/flet-packaging-update#current-approach" class="hash-link" aria-label="Direct link to Current approach" title="Direct link to Current approach" translate="no">​</a></h2>
<p>We released the first version of packaging <a class="" href="https://flet.dev/blog/packaging-apps-for-distribution">4 months ago</a> and since then, we have realized that the initial approach has multiple flaws and should be improved.</p>
<p>When you run <code>flet build apk</code> with the current Flet version it downloads Python runtime with standard library both pre-built for Android (or iOS if ran with <code>flet build ipa</code>).</p>
<p>For non-pure packages, like <code>numpy</code>, Flet is asking you to build those packages by yourself using "Python for Android" (p4a) tool from Kivy and then provide a path to "p4a" distributive where those pre-build packages could be found.</p>
<p>This is problem #1 - you are forced to struggle with a complicated process of installing "p4a" tool and compiling Python modules on your machine.</p>
<p>Problem #2 - all packages from p4a's <code>dist</code> directory will be included into a final application bundle - it could contain non-relevant packages and other junk.</p>
<p>Problem #3 - non-pure packages must be built <em>before</em> running <code>flet build</code> command. You have to analyze all dependencies of your app and separate what must be built with p4a.</p>
<p>Problem #4 - p4a "recipes" to build packages could be either very old or missing. You hope that older version of the package works with your app, try authoring a "recipe" and hope it works or submit a request for new recipe in Kivy repository.</p>
<p>When you're done with building non-pure packages using p4a, Flet requires you to specify only pure packages in <code>requirements.txt</code> which doesn't work if pure package directly or indirectly depends on non-pure (see <a href="https://flet.dev/blog/flet-packaging-update#package-dependencies" class="">example above</a>) - this is problem #5. There is a <a href="https://github.com/flet-dev/flet/issues/3114" target="_blank" rel="noopener noreferrer" class="">recent example</a> of this problem: <code>flet build</code> replaces <code>flet</code> with <code>flet-embed</code> in <code>requirements.txt</code>, but it's unable to know if there is a 3rd-party package depending on <code>flet</code>, thus both <code>flet-embed</code> and non-suitable-for-mobile <code>flet</code> are installed. This is not a solution, but a hack!</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="packaging-20">Packaging 2.0<a href="https://flet.dev/blog/flet-packaging-update#packaging-20" class="hash-link" aria-label="Direct link to Packaging 2.0" title="Direct link to Packaging 2.0" translate="no">​</a></h2>
<p>In the next iteration of Flet's packaging implementation, we are going to move away from Kivy and replace it with <a href="https://github.com/flet-dev/mobile-forge" target="_blank" rel="noopener noreferrer" class="">Mobile Forge</a>. Mobile Forge has been created by Beeware team based and their experience with Briefcase and Chaquopy. Mobile Forge is a clean-room implementation of a packaging tool for binary Python packages which is relies on <a href="https://github.com/benfogle/crossenv" target="_blank" rel="noopener noreferrer" class="">crossenv</a>.</p>
<p>The main promise of Mobile Forge with <code>crossenv</code> is that most existing non-pure Python packages will be able to compile for iOS and/or Android by simply adding a recipe with <code>meta.yaml</code> file only, without requiring any hacks or patches.</p>
<p>We are going to use Mobile Forge to pre-build the most popular non-pure Python packages for iOS and Android and host them in our own public repository. You will be able to use that tool to build and contribute other packages, non present in our repository.</p>
<p>We've created a new <a href="https://github.com/flet-dev/flet/discussions/categories/packages" target="_blank" rel="noopener noreferrer" class="">"Packages" category in Flet discussions</a> where you can post, vote and discuss requests for non-pure (native) Python packages that work with Flet (check <a href="https://github.com/flet-dev/flet/discussions/3139" target="_blank" rel="noopener noreferrer" class="">rules</a> before posting there). Flet's goal is to provide the most comprehensive catalog of pre-built Python packages and make the process of adding new packages as friendly and transparent as possible.</p>
<p>The new version of <code>flet build</code> will use a custom-made virtual pip index. This index will analyze dependencies, detect non-pure packages, and offer to pip mobile packages. For all other packages, it will fall back to PyPI.</p>
<p>The new packaging will be hopefully available in a few weeks. While we are working we encourage you to visit <a href="https://github.com/flet-dev/flet/discussions/categories/packages" target="_blank" rel="noopener noreferrer" class="">Packages</a> and see if the package you need is there. Submitting a request or voting for existing package will help us to prioritize package "recipes".</p>
<p>Thank you!</p>]]></content>
        <author>
            <name>Feodor Fitsner</name>
            <uri>ttps://github.com/FeodorFitsner</uri>
        </author>
        <category label="releases" term="releases"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Controls and theming enhancements]]></title>
        <id>https://flet.dev/blog/controls-and-theming-enhancements</id>
        <link href="https://flet.dev/blog/controls-and-theming-enhancements"/>
        <updated>2024-04-10T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[One month after the release of Flet 0.21.0, we are excited to announce the release of Flet 0.22.0.]]></summary>
        <content type="html"><![CDATA[<p>One month after the release of Flet 0.21.0, we are excited to announce the release of Flet 0.22.0.</p>
<p>This release comes with a lot of enhancements, bug fixes, and deprecations:</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="enhancements">Enhancements<a href="https://flet.dev/blog/controls-and-theming-enhancements#enhancements" class="hash-link" aria-label="Direct link to Enhancements" title="Direct link to Enhancements" translate="no">​</a></h2>
<p>This was one of the main concerns while coming up with this release. Two types of enhancements were made:</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="controls-enhancement">Controls Enhancement<a href="https://flet.dev/blog/controls-and-theming-enhancements#controls-enhancement" class="hash-link" aria-label="Direct link to Controls Enhancement" title="Direct link to Controls Enhancement" translate="no">​</a></h3>
<p>We went through the long list of already-present controls and exposed, where possible, more
properties - <a href="https://github.com/flet-dev/flet/pull/2882" target="_blank" rel="noopener noreferrer" class="">PR #2882</a>. This will grant you more power/control over the
Flet Controls you use in your awesome applications.</p>
<p>Below is the complete list:</p>
<ul>
<li class=""><a href="https://flet.dev/docs/controls/appbar/" target="_blank" rel="noopener noreferrer" class=""><code>AppBar</code></a>: elevation_on_scroll, exclude_header_semantics,
force_material_transparency, is_secondary, shadow_color, surface_tint_color, clip_behavior, title_spacing,
toolbar_opacity, title_text_style, toolbar_text_style, shape</li>
<li class=""><a href="https://flet.dev/docs/controls/alertdialog/" target="_blank" rel="noopener noreferrer" class=""><code>AlertDialog</code></a>: action_button_padding, clip_behavior, icon_padding,
shadow_color, surface_tint_color</li>
<li class=""><a href="https://flet.dev/docs/controls/banner/" target="_blank" rel="noopener noreferrer" class=""><code>Banner</code></a>: content_text_style, margin, elevation, divider_color, shadow_color,
surface_tint_color, on_visible</li>
<li class=""><a href="https://flet.dev/docs/controls/cupertinolisttile/" target="_blank" rel="noopener noreferrer" class=""><code>CupertinoListTile</code></a>: leading_size, leading_to_title</li>
<li class=""><a href="https://flet.dev/docs/controls/cupertinosegmentedbutton/" target="_blank" rel="noopener noreferrer" class=""><code>CupertinoSegmentedButton</code></a>: click_color</li>
<li class=""><a href="https://flet.dev/docs/controls/cupertinoswitch/" target="_blank" rel="noopener noreferrer" class=""><code>CupertinoSwitch</code></a>:on_label_color<!-- -->, off_label_color</li>
<li class=""><a href="https://flet.dev/docs/controls/cupertinotimerpicker/" target="_blank" rel="noopener noreferrer" class=""><code>CupertinoTimerPicker</code></a>: item_extent</li>
<li class=""><a href="https://flet.dev/docs/controls/chip/" target="_blank" rel="noopener noreferrer" class=""><code>Chip</code></a>: surface_tint_color, color, click_elevation, clip_behavior,
visual_density, border_side</li>
<li class=""><a href="https://flet.dev/docs/controls/divider/" target="_blank" rel="noopener noreferrer" class=""><code>Divider</code></a>: leading_indent, trailing_indent</li>
<li class=""><a href="https://flet.dev/docs/controls/expansiontile/" target="_blank" rel="noopener noreferrer" class=""><code>ExpansionTile</code></a>: dense, enable_feedback, visual_density</li>
<li class=""><a href="https://flet.dev/docs/controls/card/" target="_blank" rel="noopener noreferrer" class=""><code>Card</code></a>: clip_behavior, is_semantic_container, show_border_on_foreground,
variant</li>
<li class=""><a href="https://flet.dev/docs/controls/checkbox/" target="_blank" rel="noopener noreferrer" class=""><code>Checkbox</code></a>: border_side, semantics_label, shape, splash_radius, is_error,
visual_density, mouse_cursor</li>
<li class=""><a href="https://flet.dev/docs/controls/circleavatar/" target="_blank" rel="noopener noreferrer" class=""><code>CircleAvatar</code></a>: on_image_error</li>
<li class=""><a href="https://flet.dev/docs/controls/datatable/" target="_blank" rel="noopener noreferrer" class=""><code>DataTable</code></a>: clip_behavior</li>
<li class=""><a href="https://flet.dev/docs/controls/datepicker/" target="_blank" rel="noopener noreferrer" class=""><code>DatePicker</code></a>: on_entry_mode_change</li>
<li class=""><a href="https://flet.dev/docs/controls/draggable/" target="_blank" rel="noopener noreferrer" class=""><code>Draggable</code></a>: on_drag_complete, on_drag_start</li>
<li class=""><a href="https://flet.dev/docs/controls/dragtarget/" target="_blank" rel="noopener noreferrer" class=""><code>DragTarget</code></a>: on_move</li>
<li class=""><a href="https://flet.dev/docs/controls/dropdown/" target="_blank" rel="noopener noreferrer" class=""><code>Dropdown</code></a>: fill_color, hint_content, icon_content, elevation, item_height,
max_menu_height, icon_size, enable_feedback, padding, icon_enabled_color, icon_disabled_color, on_click</li>
<li class=""><a href="https://flet.dev/docs/controls/elevatedbutton/" target="_blank" rel="noopener noreferrer" class=""><code>ElevatedButton</code></a>: clip_behavior</li>
<li class=""><a href="https://flet.dev/docs/controls/floatingactionbutton/" target="_blank" rel="noopener noreferrer" class=""><code>FloatingActionButton</code></a>: clip_behavior, enable_feedback,
focus_color, foreground_color, disabled_elevation, elevation, focus_elevation, highlight_elevation, hover_elevation,
mouse_cursor</li>
<li class=""><a href="https://flet.dev/docs/controls/gridview/" target="_blank" rel="noopener noreferrer" class=""><code>GridView</code></a>: cache_extent, clip_behavior, semantic_child_count</li>
<li class=""><a href="https://flet.dev/docs/controls/iconbutton/" target="_blank" rel="noopener noreferrer" class=""><code>IconButton</code></a>: alignment, disabled_color, focus_color, enable_feedback,
hover_color, padding, splash_color, splash_radius, focus_color, mouse_cursor, visual_density</li>
<li class=""><a href="https://flet.dev/docs/controls/image/" target="_blank" rel="noopener noreferrer" class=""><code>Image</code></a>: exclude_from_semantics, filter_quality</li>
<li class=""><a href="https://flet.dev/docs/controls/listtile/" target="_blank" rel="noopener noreferrer" class=""><code>ListTile</code></a>: enable_feedback, horizontal_spacing, min_leading_width,
min_vertical_padding, selected_color, selected_tile_color, style, title_alignment, icon_color, text_color, shape,
visual_density, mouse_cursor, title_text_style, subtitle_text_style, leading_and_trailing_text_style</li>
<li class=""><a href="https://flet.dev/docs/controls/listview/" target="_blank" rel="noopener noreferrer" class=""><code>ListView</code></a>: cache_extent, clip_behavior, semantic_child_count</li>
<li class=""><a href="https://flet.dev/docs/controls/navigationbar/" target="_blank" rel="noopener noreferrer" class=""><code>NavigationBar</code></a>: animation_duration, overlay_color</li>
<li class=""><a href="https://flet.dev/docs/controls/navigationdrawer/" target="_blank" rel="noopener noreferrer" class=""><code>NavigationDrawerDestination</code></a>: bgcolor</li>
<li class=""><a href="https://flet.dev/docs/controls/navigationbardestination/" target="_blank" rel="noopener noreferrer" class=""><code>NavigationBarDestination</code></a>: bgcolor</li>
<li class=""><a href="https://flet.dev/docs/controls/navigationrail/" target="_blank" rel="noopener noreferrer" class=""><code>NavigationRail</code></a>: selected_label_text_style,
unselected_label_text_style</li>
<li class=""><a href="https://flet.dev/docs/controls/navigationrail/" target="_blank" rel="noopener noreferrer" class=""><code>NavigationRailDestination</code></a>: indicator_color, indicator_shape</li>
<li class=""><a href="https://flet.dev/docs/controls/dropdownoption/#flet.DropdownOption" target="_blank" rel="noopener noreferrer" class=""><code>Option</code></a>: alignment, on_click</li>
<li class=""><a href="https://flet.dev/docs/controls/outlinedbutton/" target="_blank" rel="noopener noreferrer" class=""><code>OutlinedButton</code></a>: clip_behavior</li>
<li class=""><a href="https://flet.dev/docs/controls/page/" target="_blank" rel="noopener noreferrer" class=""><code>Page</code></a>: locale_configuration</li>
<li class=""><a href="https://flet.dev/docs/controls/popupmenubutton/#flet.PopupMenuItem" target="_blank" rel="noopener noreferrer" class=""><code>PopupMenuItem</code></a>: height, padding,
mouse_cursor</li>
<li class=""><a href="https://flet.dev/docs/controls/popupmenubutton/" target="_blank" rel="noopener noreferrer" class=""><code>PopupMenuButton</code></a>: bgcolor, clip_behavior, elevation,
enable_feedback, icon_color, shadow_color, surface_tint_color, icon_size, padding, splash_radius, shape, on_open,
on_cancel</li>
<li class=""><a href="https://flet.dev/docs/controls/progressbar/" target="_blank" rel="noopener noreferrer" class=""><code>ProgressBar</code></a>: border_radius, semantics_label, semantics_value</li>
<li class=""><a href="https://flet.dev/docs/controls/progressring/" target="_blank" rel="noopener noreferrer" class=""><code>ProgressRing</code></a>: semantics_label, semantics_value, stroke_cap,
stroke_align</li>
<li class=""><a href="https://flet.dev/docs/controls/radio/" target="_blank" rel="noopener noreferrer" class=""><code>Radio</code></a>: focus_color, hover_color, overlay_color, splash_radius, toggleable,
visual_density, mouse_cursor</li>
<li class=""><a href="https://flet.dev/docs/controls/searchbar/" target="_blank" rel="noopener noreferrer" class=""><code>SearchBar</code></a>: keyboard_type, view_surface_tint_color, autofocus</li>
<li class=""><a href="https://flet.dev/docs/controls/selectionarea/" target="_blank" rel="noopener noreferrer" class=""><code>SelectionArea</code></a>: on_change</li>
<li class=""><a href="https://flet.dev/docs/controls/slider/" target="_blank" rel="noopener noreferrer" class=""><code>Slider</code></a>: interaction, overlay_color, mouse_cursor, secondary_track_value,
secondary_active_color</li>
<li class=""><a href="https://flet.dev/docs/controls/stack/" target="_blank" rel="noopener noreferrer" class=""><code>Stack</code></a>: alignment, fit</li>
<li class=""><a href="https://flet.dev/docs/controls/snackbar/" target="_blank" rel="noopener noreferrer" class=""><code>SnackBar</code></a>: clip_behavior, shape, on_visible, action_overflow_threshold</li>
<li class=""><a href="https://flet.dev/docs/controls/switch/" target="_blank" rel="noopener noreferrer" class=""><code>Switch</code></a>: hover_color, splash_radius, overlay_color, track_outline_color,
mouse_cursor</li>
<li class=""><a href="https://flet.dev/docs/controls/tabs/" target="_blank" rel="noopener noreferrer" class=""><code>Tabs</code></a>: divider_height, enable_feedback, indicator_thickness, is_secondary,
mouse_cursor, clip_behavior</li>
<li class=""><a href="https://flet.dev/docs/controls/textfield/" target="_blank" rel="noopener noreferrer" class=""><code>TextField</code></a>: fill_color, hover_color</li>
<li class=""><a href="https://flet.dev/docs/controls/timepicker/" target="_blank" rel="noopener noreferrer" class=""><code>TimePicker</code></a>: orientation, on_entry_mode_change</li>
<li class=""><a href="https://flet.dev/docs/types/tooltip/" target="_blank" rel="noopener noreferrer" class=""><code>Tooltip</code></a>: enable_tap_to_dismiss, exclude_from_semantics</li>
<li class=""><a href="https://flet.dev/docs/controls/verticaldivider/" target="_blank" rel="noopener noreferrer" class=""><code>VerticalDivider</code></a>: leading_indent, trailing_indent</li>
</ul>
<p>If you however feel that something lacks and should be added, don't hesitate to let us know.</p>
<p>Check out the article I wrote
concerning <code>Page.locale_configuration</code> <a href="https://ndonkohenri.medium.com/app-localization-in-flet-5b523e83ca89" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="theme-enhancements">Theme Enhancements<a href="https://flet.dev/blog/controls-and-theming-enhancements#theme-enhancements" class="hash-link" aria-label="Direct link to Theme Enhancements" title="Direct link to Theme Enhancements" translate="no">​</a></h3>
<p>The Theme class which is used for application theming in light and dark mode has equally been further enhanced.
Lots of new themes were introduced - <a href="https://github.com/flet-dev/flet/pull/2955" target="_blank" rel="noopener noreferrer" class="">PR #2955</a>.</p>
<p>See the Theming Guide <a href="https://flet.dev/docs/cookbook/theming/" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="rive-animations">Rive Animations<a href="https://flet.dev/blog/controls-and-theming-enhancements#rive-animations" class="hash-link" aria-label="Direct link to Rive Animations" title="Direct link to Rive Animations" translate="no">​</a></h2>
<p><a href="https://rive.app/" target="_blank" rel="noopener noreferrer" class="">Rive</a> is a very popular real-time interactive design and animation tool.
The newly introduced <a href="https://flet.dev/docs/rive/" target="_blank" rel="noopener noreferrer" class=""><code>Rive</code></a> Control allows you to load and visualize any Rive
animation in your applications.</p>
<p>The animation's source (<code>Rive.src</code>) can either be a local asset file or a URL - as usual, it all depends on your needs.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="parent-control">Parent Control<a href="https://flet.dev/blog/controls-and-theming-enhancements#parent-control" class="hash-link" aria-label="Direct link to Parent Control" title="Direct link to Parent Control" translate="no">​</a></h2>
<p>As requested in <a href="https://github.com/flet-dev/flet/issues/952" target="_blank" rel="noopener noreferrer" class="">#952</a>, the ability to access the parent of any control has
been added: <code>Control.parent</code>.</p>
<p>Read more on it <a href="https://ndonkohenri.medium.com/access-any-controls-parent-flet-98e2c60dfab8" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="bug-fixes">Bug Fixes<a href="https://flet.dev/blog/controls-and-theming-enhancements#bug-fixes" class="hash-link" aria-label="Direct link to Bug Fixes" title="Direct link to Bug Fixes" translate="no">​</a></h2>
<p>The below issues were successfully fixed:</p>
<ul>
<li class=""><a href="https://github.com/flet-dev/flet/issues/2560" target="_blank" rel="noopener noreferrer" class="">#2560</a> - <code>Dropdown.bgcolor</code> was not visually respected</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/2740" target="_blank" rel="noopener noreferrer" class="">#2740</a> - <code>CircleAvatar</code> not working with local asset images</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/2781" target="_blank" rel="noopener noreferrer" class="">#2781</a> - <code>'FletSocketServer'</code> Error raised on Linux</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/2826" target="_blank" rel="noopener noreferrer" class="">#2826</a> - <code>PopupMenuItem.data</code> not respected</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/2839" target="_blank" rel="noopener noreferrer" class="">#2839</a> - <code>ExpansionTile.initially_expanded</code> had no visual effect</li>
<li class=""><a href="https://github.com/flet-dev/flet/issues/2867" target="_blank" rel="noopener noreferrer" class="">#2867</a> - <code>PopupMenuButton</code> had an always-visible tooltip of "Show menu"</li>
<li class="">On some Python versions, you might have seen a RuntimeError('Event loop is closed') which usually shows up when
closing the app's window. The Python-dev
team <a href="https://github.com/python/cpython/issues/109538#issuecomment-1823306415" target="_blank" rel="noopener noreferrer" class="">fixed</a> this asyncio-related issue
recently, but this fix is only present in the versions released from the year 2024. So if you face this issue,
please <a href="https://www.python.org/downloads/" target="_blank" rel="noopener noreferrer" class="">download</a> one of the latest Python releases and replace the one used in
your environment.</li>
</ul>
<p>Special Thanks to the dynamic Flet community for reporting all the issues they encountered. We keep working hard on
solving the remaining ones.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="deprecations">Deprecations<a href="https://flet.dev/blog/controls-and-theming-enhancements#deprecations" class="hash-link" aria-label="Direct link to Deprecations" title="Direct link to Deprecations" translate="no">​</a></h2>
<p>As previously mentioned in the <a href="https://python.plainenglish.io/whats-new-in-flet-0-21-0-ca482ab4520b" target="_blank" rel="noopener noreferrer" class="">announcement</a>
concerning Flet v0.21.0, all deprecations will be completely removed from the API in version 1.0 - so you have enough
time to update your apps.</p>
<p>You must not completely memorize what has been deprecated as we've added DeprecationWarnings which will be shown
directly in your console (without breaking your app).</p>
<ul>
<li class=""><a href="https://flet.dev/docs/controls/popupmenubutton/#flet.PopupMenuButton.on_cancel" target="_blank" rel="noopener noreferrer" class=""><code>PopupMenuButton.on_cancelled</code></a> has been renamed
to <a href="https://flet.dev/docs/controls/popupmenubutton/#flet.PopupMenuButton.on_cancel" target="_blank" rel="noopener noreferrer" class=""><code>on_cancel</code></a></li>
<li class=""><a href="https://flet.dev/docs/controls/circleavatar/#flet.CircleAvatar.foreground_image_src" target="_blank" rel="noopener noreferrer" class=""><code>foreground_image_url</code></a>
and <a href="https://flet.dev/docs/controls/circleavatar/#flet.CircleAvatar.background_image_src" target="_blank" rel="noopener noreferrer" class=""><code>background_image_url</code></a> properties
of <a href="https://flet.dev/docs/controls/circleavatar/" target="_blank" rel="noopener noreferrer" class=""><code>CircleAvatar</code></a> were renamed
to <a href="https://flet.dev/docs/controls/circleavatar/#flet.CircleAvatar.foreground_image_src" target="_blank" rel="noopener noreferrer" class=""><code>foreground_image_src</code></a>
and <a href="https://flet.dev/docs/controls/circleavatar/#flet.CircleAvatar.background_image_src" target="_blank" rel="noopener noreferrer" class=""><code>background_image_src</code></a> respectively</li>
<li class=""><code>DragTargetAcceptEvent</code> used in the <a href="https://flet.dev/docs/controls/dragtarget/#flet.DragTarget.on_accept" target="_blank" rel="noopener noreferrer" class=""><code>DragTarget.on_accept</code></a> has
been renamed to <code>DragTargetEvent</code></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="documentation">Documentation<a href="https://flet.dev/blog/controls-and-theming-enhancements#documentation" class="hash-link" aria-label="Direct link to Documentation" title="Direct link to Documentation" translate="no">​</a></h2>
<p>The Flet documentation has been reorganized to ease navigation (especially for beginners/new users).</p>
<p>Upgrade to Flet 0.22.0, test your apps and let us know how you find the new features we added.
If you have any questions, please join <a href="https://discord.gg/dzWXP8SHG8" target="_blank" rel="noopener noreferrer" class="">Flet Discord server</a> or create a new thread
on <a href="https://github.com/flet-dev/flet/discussions" target="_blank" rel="noopener noreferrer" class="">Flet GitHub discussions</a>.</p>
<p>Happy Flet-ing!</p>]]></content>
        <author>
            <name>Henri Ndonko</name>
            <uri>https://github.com/ndonkoHenri</uri>
        </author>
        <category label="releases" term="releases"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Flet FastAPI and async API improvements]]></title>
        <id>https://flet.dev/blog/flet-fastapi-and-async-api-improvements</id>
        <link href="https://flet.dev/blog/flet-fastapi-and-async-api-improvements"/>
        <updated>2024-03-06T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flet makes writing dynamic, real-time web apps a real fun!]]></summary>
        <content type="html"><![CDATA[<p>Flet makes writing dynamic, real-time web apps a real fun!</p>
<p>Flet 0.21.0 further improves web apps development experience as well as using asyncio APIs in your Flet apps.</p>
<p>Here's what's new in Flet 0.21.0:</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="fastapi-with-uvicorn-replaces-built-in-web-server">FastAPI with Uvicorn replaces built-in web server<a href="https://flet.dev/blog/flet-fastapi-and-async-api-improvements#fastapi-with-uvicorn-replaces-built-in-web-server" class="hash-link" aria-label="Direct link to FastAPI with Uvicorn replaces built-in web server" title="Direct link to FastAPI with Uvicorn replaces built-in web server" translate="no">​</a></h2>
<p>From very beginning of Flet life to serve web apps there was a built-in web server written in Go
and called "Fletd". It's being started on the background when you run your app with <code>flet run --web</code>.
Fletd was part of Flet Python wheel contributing a few megabytes to its size.
Additionally, Python app was using WebSockets to talk to Fletd web server which was adding sometimes noticeable overhead.</p>
<p>Then, in <a class="" href="https://flet.dev/blog/flet-for-fastapi">Flet 0.10.0</a> we have added FastAPI support to build "serious" web apps using AsyncIO API.</p>
<p>Now, in Flet 0.21.0 built-in web server has been completely removed and replaced with FastAPI and Uvicorn. Fletd is not
a part of Flet distribution anymore.</p>
<p>Using FastAPI means there is no more communication overhead as web server is a part of Flet app.
Also, you don't need to do any additional steps to host your app in production with FastAPI -
you just use the same <code>ft.run(main)</code> command to run your app.</p>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Breaking change</div><div class="admonitionContent_BuS1"><p><code>flet_fastapi</code> package has been deprecated and its contents moved to <code>flet</code> package as <code>flet.fastapi</code>
module. If you were using FastAPI in your Flet app replace:</p><div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet_fastapi</span><br></span></code></pre></div></div><p>with</p><div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">fastapi </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> flet_fastapi</span><br></span></code></pre></div></div></div></div>
<p><strong>Use any ASGI web server for hosting</strong></p>
<p>You can host your Flet web app with any ASGI-compatible server such as <a href="https://www.uvicorn.org/" target="_blank" rel="noopener noreferrer" class="">Uvicorn</a> (used by default), <a href="https://pgjones.gitlab.io/hypercorn/" target="_blank" rel="noopener noreferrer" class="">Hypercorn</a> or <a href="https://github.com/django/daphne" target="_blank" rel="noopener noreferrer" class="">Daphne</a>.</p>
<p>Just tell Flet to export ASGI app:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_OeMC">main.py</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Page</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello ASGI!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">app </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> export_asgi_app</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>and then run with Hypercorn as:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">hypercorn main:app --bind 0.0.0.0:8000</span><br></span></code></pre></div></div>
<p><strong>Web app environment variables</strong></p>
<p>Every aspect of web app hosting can be controlled with environment variables:</p>
<ul>
<li class=""><code>FLET_FORCE_WEB_SERVER</code> - <code>true</code> to force running app as a web app. Automatically set on headless Linux hosts.</li>
<li class=""><code>FLET_SERVER_PORT</code> - TCP port to run app on. <code>8000</code> if the program is running on a Linux server or <code>FLET_FORCE_WEB_SERVER</code> is set; otherwise random port.</li>
<li class=""><code>FLET_SERVER_IP</code> - IP address to listen web app on, e.g. <code>127.0.0.1</code>. Default is <code>0.0.0.0</code> - bound to all server IPs.</li>
<li class=""><code>FLET_ASSETS_DIR</code> - absolute path to app "assets" directory.</li>
<li class=""><code>FLET_UPLOAD_DIR</code> - absolute path to app "upload" directory.</li>
<li class=""><code>FLET_MAX_UPLOAD_SIZE</code> - max allowed size of uploaded file, in bytes. Unlimited if not specified.</li>
<li class=""><code>FLET_SECRET_KEY</code> - a secret key to sign temporary upload URLs.</li>
<li class=""><code>FLET_WEB_APP_PATH</code> - a URL path after domain name to host web app under, e.g. <code>/apps/myapp</code>. Default is <code>/</code> - host app in the root.</li>
<li class=""><code>FLET_SESSION_TIMEOUT</code> - session lifetime, in seconds. Default is <code>3600</code>.</li>
<li class=""><code>FLET_OAUTH_STATE_TIMEOUT</code> - max allowed time to complete OAuth web flow, in seconds. Default is <code>600</code>.</li>
<li class=""><code>FLET_WEB_RENDERER</code> - Flutter rendering mode: <code>canvaskit</code> (default), <code>html</code> or <code>auto</code>.</li>
<li class=""><code>FLET_WEB_USE_COLOR_EMOJI</code> - <code>true</code>, or <code>True</code> or <code>1</code> to load web font with colorful emojis.</li>
<li class=""><code>FLET_WEB_ROUTE_URL_STRATEGY</code> - <code>path</code> (default) or <code>hash</code>.</li>
<li class=""><code>FLET_WEBSOCKET_HANDLER_ENDPOINT</code> - custom path for WebSocket handler. Default is <code>/ws</code>.</li>
<li class=""><code>FLET_UPLOAD_HANDLER_ENDPOINT</code> - custom path for upload handler. Default is <code>/upload</code>.</li>
<li class=""><code>FLET_OAUTH_CALLBACK_HANDLER_ENDPOINT</code> - custom path for OAuth handler. Default is <code>/oauth_callback</code>.</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="async-first-framework">Async-first framework<a href="https://flet.dev/blog/flet-fastapi-and-async-api-improvements#async-first-framework" class="hash-link" aria-label="Direct link to Async-first framework" title="Direct link to Async-first framework" translate="no">​</a></h2>
<p>Flet is now async-first framework which means you don't have to decide whether your app is entirely sync or async, but you can mix both sync and async methods in the same app.</p>
<p>For example, in Flet 0.21.0 you can write an app like this:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> time</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> asyncio</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Page</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">handler</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">sleep</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Handler clicked"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">handler_async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> asyncio</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">sleep</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Async handler clicked"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ElevatedButton</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Call handler"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> on_click</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">handler</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ElevatedButton</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Call async handler"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> on_click</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">handler_async</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>In the example above a click on one button is handled by a "blocking" handler while a click
on second button calls asynchronous handler. The first handler is run in a <code>threading.Thread</code> while second handler is run in <code>asyncio.Task</code>.</p>
<p>Also, notice in <code>async def</code> handler you are not required to use <code>await page.add_async()</code> anymore, but a regular <code>page.add()</code> works just fine.</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>API changes</div><div class="admonitionContent_BuS1"><p>Most of <code>Page.&lt;method&gt;_async()</code> and <code>Control.&lt;method&gt;_async()</code> methods have been deprecated and their <code>Page.&lt;method&gt;()</code> and <code>Control.&lt;method&gt;()</code> counterparts should be used instead.</p><p>The only exception here is methods returning results, like those ones in <code>Audio</code> control: you still have to use async methods in async event handlers.</p></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="custom-controls-api-normalized">Custom controls API normalized<a href="https://flet.dev/blog/flet-fastapi-and-async-api-improvements#custom-controls-api-normalized" class="hash-link" aria-label="Direct link to Custom controls API normalized" title="Direct link to Custom controls API normalized" translate="no">​</a></h2>
<p>In this Flet release we also re-visited API for writing custom controls in Python.</p>
<p>As a result <code>UserControl</code> class has been deprecated. You just inherit from a specific control with layout that works for your needs.</p>
<p>For example, <code>Countdown</code> custom control is just a <code>Text</code> and could be implemented as following:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> asyncio</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Countdown</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">__init__</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> seconds</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token builtin">super</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">__init__</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">seconds </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> seconds</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">did_mount</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">running </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">True</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run_task</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">update_timer</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">will_unmount</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">running </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">False</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">update_timer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">while</span><span class="token plain"> self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">seconds </span><span class="token keyword" style="color:#00009f">and</span><span class="token plain"> self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">running</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            mins</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> secs </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token builtin">divmod</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">seconds</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">value </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"{:02d}:{:02d}"</span><span class="token punctuation" style="color:#393A34">.</span><span class="token builtin">format</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">mins</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> secs</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">update</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> asyncio</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">sleep</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">seconds </span><span class="token operator" style="color:#393A34">-=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Page</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Countdown</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">120</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Countdown</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>Notice the usage of <code>self.page.run_task(self.update_timer)</code> to start a new task.
There is also <code>self.page.run_thread()</code> method that must be used by control developer to start a new background job in a thread.</p>
<p>If you want to spawn your own tasks or threads Flet provides the current event loop and thread executor via <code>Page.loop</code> and <code>Page.executor</code> properties respectively.</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>API changes</div><div class="admonitionContent_BuS1"><p><code>Control._before_build_command()</code> replaced with <code>Control.before_update()</code></p><p><code>Control.build()</code> should not return any control now, but must update inherited control properties, for example:</p><div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">build</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">controls</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">append</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Something"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div><p><code>Control.did_mount_async()</code> and <code>Control.will_unmount_async()</code> are deprecated. Use <code>Control.did_mount()</code> and <code>Control.will_unmount()</code> instead.</p></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="new-cupertino-controls">New Cupertino controls<a href="https://flet.dev/blog/flet-fastapi-and-async-api-improvements#new-cupertino-controls" class="hash-link" aria-label="Direct link to New Cupertino controls" title="Direct link to New Cupertino controls" translate="no">​</a></h2>
<p>This Flet release adds more Cupertino controls to make your apps shine on iOS:</p>
<ul>
<li class=""><code>CupertinoActivityIndicator</code></li>
<li class=""><code>CupertinoActionSheet</code></li>
<li class=""><code>CupertinoSlidingSegmentedButton</code></li>
<li class=""><code>CupertinoSegmentedButton</code></li>
<li class=""><code>CupertinoTimerPicker</code></li>
<li class=""><code>CupertinoPicker</code></li>
<li class=""><code>CupertinoDatePicker</code></li>
<li class=""><code>CupertinoContextMenu</code></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="accessibility-improvements">Accessibility improvements<a href="https://flet.dev/blog/flet-fastapi-and-async-api-improvements#accessibility-improvements" class="hash-link" aria-label="Direct link to Accessibility improvements" title="Direct link to Accessibility improvements" translate="no">​</a></h2>
<p>Now Flet has complete implementation of <code>Semantics</code> control and new <code>SemanticsService</code> control.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_vjPI" id="app-lifecycle-change-event">App lifecycle change event<a href="https://flet.dev/blog/flet-fastapi-and-async-api-improvements#app-lifecycle-change-event" class="hash-link" aria-label="Direct link to App lifecycle change event" title="Direct link to App lifecycle change event" translate="no">​</a></h2>
<p>There is a new <code>Page.on_app_lifecycle_state_change</code> event that allows listening for changes in the application lifecycle.</p>
<p>For example, you can now update UI with the latest information when the app becomes active (brought to the front). This event works on iOS, Android, all desktop platforms and web!</p>
<p>The following app lifecycle transitions are recognized:</p>
<ul>
<li class=""><code>SHOW</code></li>
<li class=""><code>RESUME</code></li>
<li class=""><code>HIDE</code></li>
<li class=""><code>INACTIVE</code></li>
<li class=""><code>PAUSE</code></li>
<li class=""><code>DETACH</code></li>
<li class=""><code>RESTART</code></li>
</ul>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_BuS1"><p>Read more about each <a href="https://flet.dev/docs/controls/page/#flet.Page.on_app_lifecycle_state_change" target="_blank" rel="noopener noreferrer" class="">lifecycle state</a>.</p></div></div>
<p>Here's a small example of how this event can be used:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> flet </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ft</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">page</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Page</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">app_lifecycle_change</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">AppLifecycleStateChangeEvent</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">state </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">AppLifecycleState</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">RESUME</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Update UI with fresh data!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">on_app_lifecycle_state_change </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> app_lifecycle_change</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    page</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello World"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ft</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>Flet 0.21.0 release has some breaking changes. Upgrade to it, test your apps and let us know how it worked for you.
Join <a href="https://discord.gg/dzWXP8SHG8" target="_blank" rel="noopener noreferrer" class="">Flet Discord server</a> or create a new thread
on <a href="https://github.com/flet-dev/flet/discussions" target="_blank" rel="noopener noreferrer" class="">Flet GitHub discussions</a>.</p>
<p>Enjoy!</p>]]></content>
        <author>
            <name>Feodor Fitsner</name>
            <uri>ttps://github.com/FeodorFitsner</uri>
        </author>
        <category label="releases" term="releases"/>
    </entry>
</feed>