website/blog/2026-04-01-flet-v-0-84-release-announcement.md
Flet 0.84.0 is a developer-experience release: new documentation website and re-worked examples.
Highlights in this release:
If you use pip:
pip install 'flet[all]' --upgrade
If you use uv with pyproject.toml and want to upgrade everything:
uv sync --upgrade
If you want to upgrade only Flet packages:
uv sync --upgrade-package flet \
--upgrade-package flet-cli \
--upgrade-package flet-desktop \
--upgrade-package flet-web
The Flet website has always been built on Docusaurus - 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.
For Flet "v1", @ndonkoHenri made a huge push by moving all API docs into Python docstrings and configuring MkDocs + Material for MkDocs + mkdocstrings to serve Flet documentation. It was a great and timely decision to make docstrings the single source of truth.
And it worked, but with some quirks:
Then, one day, we saw this warning in a build log and got a feeling that something was off:
:::warning WARNING - MkDocs 2.0 is incompatible with Material for MkDocs :::
Apparently, there is a whole story 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 Zensical, a MkDocs rewrite in Rust that is backward-compatible but launched with many plugins still missing.
We decided to bring docs back to Docusaurus - but this time with a tool that keeps docstrings as the single source of truth.
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 Griffe, produce JSON data and MDX partials, and let Docusaurus render everything using custom MDX components and remark plugins.
The pipeline looks like this:
api-data.json with all API entries and a cross-reference map (xref_map) that resolves symbol names to documentation URLs.It's a modern Python project, managed with uv and configured entirely via pyproject.toml.
We switched from mkdocstrings-python-xref 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.
Before (mkdocstrings):
"""See [Page][flet.] and [Control.visible][flet.] for details."""
After (reST roles):
"""See :class:`~flet.Page` and :attr:`flet.Control.visible` for details."""
The supported roles are :class:, :attr:, :meth:, :func:, :mod:, :data:, and :obj:. The ~ prefix shortens the display name - :class:~flet.Page`` renders as just "Page" while still linking to the full path.
Here's what it looks like in VS Code - docstring links are rendered and navigable right in the tooltip:
In addition to the broken-link checks that Docusaurus performs during build, we added a custom CI script with strict validation:
:class:, :attr:, :meth: markers that were not resolved to links.<CodeExample> components that reference non-existent example files.api-data.json.If any check fails, the build fails. No broken docs make it to production.
The migration from MkDocs to Docusaurus brought exactly what we hoped for:
CrocoDocs is not yet available on PyPI, but if you'd like to adopt it for your Python project - let me know!
More info:
Every Flet example is now a standalone project with its own pyproject.toml and rich metadata. Here's why we made this change:
Better discovery. 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.
Easier to build and run. 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 flet run.
Self-contained. Every project includes all its dependencies (flet_charts, flet_map, etc.), permissions, bundle IDs, and assets needed to successfully build and run on any platform.
Before - a flat Python file with no metadata:
sdk/python/examples/controls/
├── button_examples.py
├── canvas_examples.py
└── ...
After - a structured project directory:
sdk/python/examples/controls/
├── material/
│ └── button/
│ ├── basic/
│ │ ├── main.py
│ │ └── pyproject.toml
│ ├── icons/
│ │ ├── main.py
│ │ └── pyproject.toml
│ └── styling/
│ ├── main.py
│ └── pyproject.toml
├── core/
│ └── canvas/
│ ├── bezier_curves/
│ ├── brush/
│ └── ...
└── cupertino/
└── cupertino_button/
└── basic/
Each pyproject.toml includes Gallery and MCP metadata:
[project]
name = "button-basic"
version = "1.0.0"
description = "Basic enabled and disabled Button examples."
keywords = ["button", "material", "basic", "disabled"]
dependencies = ["flet"]
[tool.flet.gallery]
categories = ["Buttons/Button"]
[tool.flet.metadata]
title = "Basic button"
controls = ["SafeArea", "Column", "Button"]
layout_pattern = "inline-actions"
complexity = "basic"
features = ["enabled and disabled states"]
In total, 466 examples were migrated to this format.
More info:
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.
Try it and share feedback in GitHub Discussions or on Discord.
Happy Flet-ing!