Every app store page says something nice about privacy. “We respect your data.” “Your privacy matters to us.” These sentences cost nothing to write, and you have no way to check them.
So instead of another sentence, here is a list. We took three apps that are live in the stores today, opened their dependency files, and wrote down everything they pull in. Then we searched the full dependency tree for the things a privacy claim is really about: analytics, ads, crash reporting, install attribution and push services.
The apps are Oxi Pomodoro, Habit Observer and Neon Grid Sudoku. All three are written in Flutter, so the same lists apply to the Android and the iOS versions.
How to read a dependency list
A Flutter app names its direct dependencies in one file. Each of those can pull in its own dependencies, and so on. The second file, the lock file, holds the full tree: every package that ends up in the build.
The direct list tells you what the developer chose. The full tree tells you what actually ships. A tracking library can hide three levels down, inside a package that looks harmless, so we checked both.
Oxi Pomodoro
A focus timer. 10 direct dependencies, 111 packages in the full tree.
- State and storage: a state management package, and the standard key-value store for settings (your last timer, recent timers, chosen sound).
- Sound and vibration: an audio player for the alarm, a vibration package, and a package that keeps the screen awake while the timer runs.
- Notifications: local notifications for “time is up” when the app is in the background, plus a time zone package to schedule them.
- The rest: opening a link in the browser, reading the app version for the About screen, and the standard icon set.
Habit Observer
A habit tracker. 22 direct dependencies, 126 packages in the full tree.
- Data: a local SQLite database for your habits and history, a key-value store for settings, and file paths on the device.
- Interface: a calendar widget, a day picker, SVG images, icons, and translations for the supported languages.
- Reminders: local notifications and time zones, same as above.
- Purchase: the official in-app purchase package, for the one-time PRO upgrade.
- Desktop: window management, because the same code runs on macOS and Windows.
Neon Grid Sudoku
A puzzle game. 9 direct dependencies, 103 packages in the full tree.
- Game: an audio package for sound effects, state management, and a key-value store for saved games, stats and streaks.
- Store rating: the official package that shows the system’s own “rate this app” dialog. It asks the store app to show it, and only for players who keep coming back.
- The rest: keeping the screen awake during a game, the app version, links, file paths and window management for desktop.
What is not there
Across all three full trees, 340 packages in total, we found:
- no analytics or event tracking
- no advertising SDK
- no crash reporting service
- no install attribution or “growth” tools
- no push notification service
- no account or login system
- no remote configuration
This is the part that matters most. A privacy policy is a promise. A dependency tree is what the app can actually do. If there is no analytics package in the build, there is nothing in the app that could send analytics.
The permission check
Dependencies show what code is inside. Permissions show what the system lets that code do. On Android, an app can only reach the network if it declares the internet permission.
- Oxi Pomodoro does not have the internet permission at all. Android blocks every network connection for it. Even if we wanted to send data, the phone would not let us. It asks only for notifications, exact alarms (so the timer alert arrives on time), vibration, and the right to restore a pending alarm after a restart.
- Habit Observer has internet access for one reason: the store’s purchase component needs it to process the PRO upgrade. Your habits never leave the device; they live in the local database.
- Neon Grid Sudoku makes no network requests, and from version 1.3.9 it no longer asks for the internet permission either.
You can check this yourself. On Android, open the app’s settings page and look at its permissions. F-Droid clients show the full permission list before you install anything from our F-Droid repository.
What we give up
A list like this has a cost, and it is fair to say what it is.
We do not get crash reports. When an app crashes on a phone we have never seen, we only learn about it if someone tells us. A crash reporting service would tell us in minutes. Instead, we test on real devices before every release and read store reviews and emails carefully.
We do not know how people use the apps. We can’t tell which screen people skip or where they quit. Product decisions come from our own use, from feedback, and from the download and sales numbers the stores give every developer anyway.
Some features are harder. Sync between devices, for example, needs a place to store data. When we build that, we build it so you own the place, not us.
We think these are the right tradeoffs for small, focused apps. A timer does not need to know who you are. A sudoku game does not need to report to anyone. We wrote more about the reasoning in why we don’t track users.
Why publish this at all
Because it can be checked. “We respect your privacy” can’t be checked. “There is no analytics package in these 340 packages, and this app has no internet permission” can be. If a future version ever adds something to these lists, the difference will be visible to anyone who looks.
We would like more developers to publish lists like this. It takes an hour, and it turns a marketing sentence into a fact.