website/docs/updates/breaking-changes/v0-86-0-app-files-unpacked-read-only-bundle.md
:::note This guide is accurate as of Flet 0.86.0. Later releases might add new APIs or additional migration paths.
The breaking changes and deprecations index lists the guides created for each release. :::
Flet 0.86.0 (with serious_python 4.0.0) changes how a packaged app's Python files are shipped and
where the app reads and writes data:
app.zip extraction. On
Android the app ships as a stored app.zip asset inside the APK and is unpacked once
(version-keyed) to the app's files directory on the first launch after an install/update. Web
(Pyodide) is unchanged..app, iOS bundle, Program Files, the APK).FLET_APP_STORAGE_DATA.FLET_APP_STORAGE_DATA now maps to the OS application support directory (a data subdir),
not the user's Documents folder.FLET_APP_STORAGE_DATA (durable),
the new FLET_APP_STORAGE_CACHE (regenerable), and FLET_APP_STORAGE_TEMP (now the OS temp
dir, previously the cache dir).flet run (dev mode) now sets the working directory to a hidden, git-ignored
<project>/.flet/storage/data, mirroring a built app.Previously your Python sources were zipped into app/app.zip, shipped as a Flutter asset, and
extracted at runtime on first launch — while the stdlib and site-packages already shipped unpacked
inside the bundle. Lifting app-file handling into serious_python removes the first-launch unzip and
the hash bookkeeping, and puts your code in the same place as the stdlib. Because that place is
read-only, the working directory has to move somewhere writable — and the natural home for app data
is the OS application support directory, which is app-private on every platform (no Documents
clutter, no manual scoping).
The app directory is read-only. Relative writes resolve against the current working directory,
which is now FLET_APP_STORAGE_DATA (a writable, durable, app-private dir). open("app.db", "w") and
sqlite3.connect("app.db") keep working — the file just lands in the data dir instead of next to your
.py files, and now persists across app updates.
__file__, not relative pathsRelative reads of files you bundle with your app (e.g. open("seed.json")) no longer resolve
against your app folder. Read bundled data relative to your module instead:
from pathlib import Path
SEED = Path(__file__).parent / "seed.json"
data = SEED.read_text()
or use importlib.resources, or place the file under your Flet assets/ directory and resolve it via
FLET_ASSETS_DIR.
| Variable | Meaning | Lifetime |
|---|---|---|
FLET_APP_STORAGE_DATA | Durable app data (= the working directory) | Never auto-deleted; backed up |
FLET_APP_STORAGE_CACHE | Regenerable cache (new) | OS may purge under storage pressure |
FLET_APP_STORAGE_TEMP | OS temp / scratch (changed — was the cache dir) | Most volatile; may vanish between launches |
If you relied on FLET_APP_STORAGE_TEMP for data that should survive (it used to be the cache dir),
switch to FLET_APP_STORAGE_CACHE (or FLET_APP_STORAGE_DATA for must-keep data).
FLET_APP_STORAGE_DATA (= the working directory):
| Platform | Location |
|---|---|
| Windows | %APPDATA%\<company>\<product>\data (e.g. C:\Users\<User>\AppData\Roaming\<company>\<product>\data) |
| macOS | ~/Library/Application Support/<bundle-id>/data (sandboxed apps: redirected into the app container) |
| Linux | ${XDG_DATA_HOME:-~/.local/share}/<app-id>/data |
| iOS | <app-sandbox>/Library/Application Support/<bundle-id>/data |
| Android | /data/data/<package>/files/data |
flet run (dev) | <project>/.flet/storage/data |
FLET_APP_STORAGE_CACHE and FLET_APP_STORAGE_TEMP:
| Platform | FLET_APP_STORAGE_CACHE | FLET_APP_STORAGE_TEMP |
|---|---|---|
| Windows | %LOCALAPPDATA%\<company>\<product> | %TEMP% (…\AppData\Local\Temp) |
| macOS | ~/Library/Caches/<bundle-id> | $TMPDIR (e.g. /var/folders/.../T/) |
| Linux | ${XDG_CACHE_HOME:-~/.cache}/<app-id> | system temp ($TMPDIR, fallback /tmp) |
| iOS | <app-sandbox>/Library/Caches/<bundle-id> | <app-sandbox>/tmp |
| Android | getCacheDir() (/data/data/<package>/cache) | same as CACHE (getCacheDir()) |
flet run (dev) | <project>/.flet/storage/cache | <project>/.flet/storage/temp |
flet run dev storageflet run now creates a hidden <project>/.flet/ directory (with storage/{data,cache,temp}) and
runs your app with the working directory set to .flet/storage/data, so dev behaves like a built app
(including the read-shipped-files change above). The directory writes its own .gitignore and is
ignored by Git automatically; the old visible storage/ directory is no longer used.
0.86.0FLET_APP_STORAGE_DATA,
FLET_APP_STORAGE_CACHE,
FLET_APP_STORAGE_TEMP