Taking Over an Unfinished Flutter App: My Audit Checklist (Security First)
"The app is 80% done, the previous developer stopped answering, can you finish it?" If you freelance long enough, you get this message. Sometimes the project is in good shape. Sometimes the last 20% is really 70%. And so
"The app is 80% done, the previous developer stopped answering, can you finish it?" If you freelance long enough, you get this message. Sometimes the project is in good shape. Sometimes the last 20% is really 70%. And sometimes the repository itself is a risk to your own machine.
I'm a freelance Flutter and WordPress developer in Famagusta, North Cyprus. This is the checklist I go through before I quote, in the order I do it.
1. Don't run it yet: read it in isolation
The first rule: a repository from a stranger is untrusted code. Fake "fix this bug in our repo" tasks are a known way to steal SSH keys, browser cookies and saved passwords from developers. So the first pass is reading, not running, and anything that executes happens in a throwaway environment (a GitHub Codespace on a separate account, or a VM), never on the laptop that holds my client logins.
Things I read before any flutter pub get or gradle task:
-
android/build.gradle,android/app/build.gradleandsettings.gradle: anything that callsexec,commandLineor downloads scripts at build time. -
android/gradle/wrapper/gradle-wrapper.propertiesand the wrapper JAR: does the distribution URL point toservices.gradle.org? -
ios/Podfileand any "Run Script" build phases in the Xcode project. -
pubspec.yaml: git dependencies pointing to unknown forks, or path dependencies outside the repo. -
.vscode/tasks.json: a task with"runOn": "folderOpen"runs the moment you open the folder. Open unknown projects in Restricted Mode. - Any
package.json(web tooling, Firebase functions):preinstall/postinstallscripts.
Only when that looks clean do I build, and still in the isolated environment. The APK it produces can then be tested on a spare phone or a cloud emulator.
2. Secure what belongs to the client
Before touching code, I make sure the client actually owns their project:
- Git repo in their organisation, not the previous developer's personal account.
- Google Play Console and Apple Developer accounts in the client's name.
- Owner access to Firebase / Supabase / the backend, plus API keys for maps, payments and push notifications.
- The Figma file and assets.
If any of this is missing, that is the first milestone, because without it nothing else is safe to build on.
3. Measure the real state
Then the honest part. I run through:
-
flutter analyzeand the number of warnings (and whetheranalysis_options.yamlsilences everything). - Flutter / Dart SDK constraints vs. current stable, and
flutter pub outdated. - State management: one consistent approach, or three mixed together?
- Secrets in source: API keys or passwords committed in Dart files or
google-services.jsonfor the wrong project. - Tests: any at all? Do they pass?
- Every screen on a real device: which features work, and which only look finished.
The output is a short written report for the client in plain language: what works, what needs fixing, what is missing.
4. Finish, refactor or rebuild
Most rescues end up in one of three buckets:
| Situation | Recommendation |
|---|---|
| Clean structure, missing features | Finish as is |
| Works, but features break each other | Refactor key modules first, then finish |
| Weak foundation or very old SDK | Rebuild, keeping designs, backend and data |
Rebuilding sounds expensive, but it is often cheaper than fighting a codebase where every change breaks two other screens.
5. Make the next handover painless
Whatever happens, I set the project up so the client is never stuck again: weekly pushes to their repo, regular test builds they can install, store accounts and keys in their name, and a short README that explains how to build and release.
I wrote a non-technical version of this for business owners here: Unfinished App? How to Rescue a Half-Built App and Launch It. If you've taken over a project that turned out to be a trap, I'd love to hear what you check first.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.