MyFamilyTracker
Real-time family location sharing — Firebase Realtime DB for sub-second propagation, WorkManager + ForegroundService for OS-compliant background collection, geofencing via Google Maps API.
Speed and quality feel like a trade-off but they're not — in the right setup, quality practices make you faster by preventing rework. Here's the framework I use to ship frequently while keeping apps stable.
On this page
The conventional wisdom is that you can have fast or quality, not both. After maintaining 22 apps for years, I've found the opposite: the right quality practices make you faster, not slower.
Here's the framework.
When developers skip quality steps to ship faster:
When quality steps are in place:
The second path is faster overall. The cost of quality is visible. The cost of rework is invisible until it's painful.
Full quality practices for large teams (dedicated QA, code reviews, staging environments) don't apply to solo development. The relevant practices are:
Must-have:
High value:
Nice to have at scale:
You don't need everything. You need the right things.
Morning (2-3 hours): Deep work — new features. No meetings, no support, no review. Pure development on the most important item for the current app.
Midday (30 min): CI triage. Any CI failures from overnight? Fix them before starting new work. Broken CI is a blocker.
Afternoon (1-2 hours): Maintenance and support. Bug fixes, dependency updates, reviewing analytics from recent releases.
Before stopping: Commit + push. Never end the day with uncommitted code. CI runs overnight. Morning starts with a green build or a clear failure to fix.
Developing a feature over multiple days? Use a feature flag so partial work can be committed to main without affecting users:
object FeatureFlags {
val TASK_SHARING = BuildConfig.DEBUG || remoteConfig.getBoolean("task_sharing_enabled")
}
// In your UI
if (FeatureFlags.TASK_SHARING) {
ShareButton(task = task)
}This means:
Every manual step I automate saves time on every future release:
Initial setup: 4-8 hours. Ongoing savings: 30+ minutes per release, per app, forever.
The automation flywheel: the more apps you add, the more valuable each automation becomes.
For each new app, I build tests in this order:
Week 1 (during initial development):
Week 2-4:
Ongoing:
Result: a suite of 50-80 tests that runs in under 2 minutes, catches real bugs, and provides confidence in refactoring.
This is not "proper" test coverage by enterprise standards. It's proportionate to a solo developer's capacity and significantly better than no tests.
The practices that feel like overhead but actually accelerate you:
Null safety (Kotlin's ?): Eliminates an entire category of crashes. You don't ship NullPointerExceptions. Finding one in development takes seconds. In production it takes hours.
Sealed classes for state: Forces you to handle all cases. The compiler tells you when you've missed one. Beats runtime discovery.
Consistent architecture: Identical structure across all apps means zero context-switching overhead. New features take the same amount of time in app #22 as in app #2.
Dependency injection (Hilt): Makes testing possible and refactoring safe. Without it, every component is a god object with hidden dependencies.
These aren't about correctness in isolation. They're about speed over the lifetime of the codebase.
My approach:
Frequent small releases are less risky than infrequent large ones. Each release is smaller, easier to test, and easier to roll back if something goes wrong.
Sudarshan Chaudhari
AI Systems Builder / Product Engineer
Bangkok, Thailand
Solo Android developer with 13+ years in QA, building Android apps, AI automation systems, and developer tools at SudarshanTechLabs.
Related Posts
Related Apps
Real-time family location sharing — Firebase Realtime DB for sub-second propagation, WorkManager + ForegroundService for OS-compliant background collection, geofencing via Google Maps API.
Building something? Available for Android dev and QA consulting.
Work with meComments — powered by Giscus