Skip to content
Blue Digital Marketing Agency Hero Section Desktop Prototype (11)
  • Services
    • Web Development
    • Mobile Development
    • Legacy App Modernization
    • Microservices Development & Consulting
    • Project Takeover
    • Urgent Help
    • Code Audit
    • Project Analysis
    • CTO as a Service
  • Industries
    • Sports
  • Our Work
  • About
    • About Us
    • How We Work
    • Tech Stack
  • Blog
Contact Us
Technology

How We Transformed a Pickup Soccer Platform into an App for Thousands of Players

October 30, 2025 Artsemi Nekhai

This is the story of how our Android team helped Plei — a fast-growing pickup soccer platform — transform its mobile experience using Jetpack Compose, Kotlin Coroutines, and Firebase. In this article, we’ll share how we enhanced the user experience, improved reliability, and made it easier for players to discover and join games.

App modernization story

When we first joined the Plei project, we could immediately feel its energy. The Plei team’s passion for connecting players and keeping local fields active was impressive. Our mission as Android developers was clear: turn that passion into a mobile app that was fast, intuitive, and reliable.

We wanted every interaction — from discovering a match to paying for a spot — to feel effortless. Our focus was on stability, performance, design, and building a sports app that not only worked well, but also captured the spirit of soccer. ⚽

Building a Foundation for Growth

When we arrived, Plei already had an Android app with thousands of users. However, rapid feature growth had started to outpace the existing codebase. Our first goal was to strengthen stability and prepare the product for sustainable expansion.

In the past, the app grew too fast, which impacted code quality. Over time, a significant part of the logic had become tightly coupled: UI components interacted directly with data sources, and business rules were scattered across modules. This made testing and maintenance difficult — even small updates could lead to unexpected effects on other parts of the system. To make the app more stable and ready for long-term growth, we needed a cleaner structure and a clear separation of responsibilities.

We restructured the project using the Clean Architecture principles, splitting it into three layers:

  • UI/Presentation – screens, ViewModels, and UI logic.
  • Domain – pure business rules and use cases not related to Android APIs.
  • Data – repositories and data sources (network, local database, and caches).
App modernization: Android clean architecture

This separation reduced coupling, allowing us to modify UI, APIs, and caching strategies with minimal impact on one another.

Discover how clean code architecture strengthens both development and business outcomes — making apps more maintainable, scalable, and aligned with user needs.

To handle state and data flow across layers, we used a custom MVI (model-view-intent) solution. The new MVI solution made events and states more predictable and allowed us to test the UI behavior. We combined it with Kotlin Coroutines and Flow for reactive streams API and structured concurrency. This improved responsiveness and allowed us to write error-handling patterns clearer. 

We used Dagger 2 for dependency management but did not stop there: we made our setup constructor injection-friendly all the way through. It was done to improve automated testing. The result was a componentized codebase with features that could be developed and shipped separately.

A Fresh Visual Experience with Jetpack Compose

One of the most noticeable upgrades was the introduction of a new modern UI. We transitioned large parts of the app to Jetpack Compose, Google’s declarative toolkit. Instead of a long and hard to control full rewrite, we took an incremental migration approach. This approach allowed us to introduce modern UI improvements one by one, monitor performance and user metrics in real time, and ensure that the app remained stable throughout the migration.

Jetpack Compose allowed for faster UI development, easier maintenance, and seamless integration of animations and interactive components. Our process included:

  1. Design alignment and prototyping. We worked closely with designers to turn mockups into functional UI components.
  2. Composable component library. We created a shared UI library for buttons, cards, list rows, and consistent spacing/typography. It made new screens consistent and increased the speed of development.
  3. Micro-interactions and animations. Using Lottie Compose and Compose’s motion APIs for animation, we delivered expressive onboarding experiences and micro-interactions. Where legacy Views were required, we bridged them with ComposeView to preserve UX consistency.
  4. Performance and lists. We used Glide Compose to process images and Paging 3 with Compose’s LazyColumn and PagingData to manage long lists. Data was loaded reactively, with placeholders and incremental content rendered instead of waiting for the full payload.
  5. Gradual migration for stability. Each new Compose screen shipped along with existing XML screens. This hybrid approach allowed us to monitor performance and user metrics during migration.
App modernization: Jetpack Compose migration

The result was a cleaner, more responsive app that let designers iterate faster and offered users a streamlined unified experience.

Streamlining Payments and Logistics

Seamless payments and bookings are essential for engagement. We rebuilt Plei’s payment system using Stripe, Braintree, and Google Pay, with smart logic that charged only when games were confirmed — preventing overpayments and unnecessary refunds.

Apart from the backend logic, we also streamlined and made payments clear on the user side. We gave clear indications telling users when and how payment was done. Users could attach saved cards and Google Pay accounts for one-tap checkout. We also developed friendly, contextual messaging for edge cases like failed payments or partial refunds, turning what once was a frustrating experience into a reassuring one. 

Each point in the payment process was instrumented with analytics, enabling the product team to identify and optimize friction points in real time. Transactions were tokenized to keep sensitive data secure and were made idempotent to prevent duplicate payments during network issues. We deployed the new payment logic using LaunchDarkly feature flags before a full deployment.

Payment system modernization

These updates made Plei’s booking system secure and trustworthy, giving players confidence that every tap sends them exactly where they’re supposed to go.

Explore the essentials of multi-sport app development, from scheduling and tournaments to payments, and architecture.

Matching Players with the Right Games

One of the core features of the Plei app was helping users discover games nearby. We developed a location-based discovery feature using Play Services Location and Maps Compose to allow for seamless map interaction and accurate listings of nearby games.

To ensure a smooth and efficient experience, we combined Firestore real-time listeners with local persistence (Room + DataStore), allowing players to navigate the app even when the connection was poor. Once connectivity was restored, Firestore listeners and Kotlin Flows automatically updated the app so that local data matched the latest server state. 

We also improved filtering and scheduling, enabling users to find games by location, time, skill level, or field type quickly. With Paging 3, we ensured smooth scrolling even in areas packed with events.

Discovery experience modernization

Quality You Can Rely On

Reliability was non-negotiable. We made testing an integral part of daily development.

In order to support useful tests, we wanted to use constructor injection throughout the codebase. As ViewModel creation in Android was factory-dependent, we created a standalone ViewModelProvider.Factory pattern (similar in concept to Assisted Injection) so that ViewModels could take constructor arguments neatly and be initialized in tests using mocked dependencies.

Having that groundwork built, we rolled out a four-stage testing strategy:

  1. ViewModels first – make presentation logic and user flows explicit.
  2. Utility functions – test cross-cutting helpers, formatters, and small pure functions on which the other layers depended.
  3. Use cases – verify domain rules and business flows.
  4. Repositories – test data access paths (API error flows, caching, migrations) with mock network and local layers.
App testing strategy

We applied JUnit, MockK, Robolectric for JVM-level UI tests, and Espresso for instrumentation where necessary. Coupled with Firebase Crashlytics and structured logging through Timber, our CI builds could now detect regressions early and make refactors safe. Fastlane and Firebase Distribution assisted us in staging releases to QA groups prior to full rollouts.

Details That Delight

Sometimes, it is small things that make a product truly wonderful to use. We invested in small details that conveyed a feeling of care and responsiveness — from the initial contact to the final whistle.

Clear and Organized Game Descriptions
We added Markdown support for game descriptions so organizers could use markdown, include links, or make lists. With a good markdown rendering library, descriptions looked nice in the app, allowing users to see properly formatted info about every game without cluttered screens or unnecessary text.

Effortless Image Handling
Image updates became fast and enjoyable. Glide Compose and a built-in image cropper simplified avatar and team photo editing. Caching and resizing were optimized for quick loading and image quality preservation on slower networks.

Instant Notifications
For user retention, we employed push notifications via Firebase Cloud Messaging (FCM). Users were now informed of new game arrivals, scheduled updates, or booking confirmations — FCM ensured efficient and effective delivery of notifications to users.

Seamless Support
In-app assistance through Intercom allowed users to ask questions within the app and get quick responses from the Plei team without having to switch to email or messaging applications.

Smart Analytics and Controlled Updates
Using Mixpanel and AppsFlyer, we tracked interactions to understand which features players valued most. LaunchDarkly feature flags allowed us to add new functionality incrementally, test our hypotheses with safety nets, and ship changes without expecting users to update the app.

Memorable UI Touches
Small UI touches made a big difference. Lottie animations, smooth transitions, and UI feedback made the app feel dynamic and sporty — every tap felt like passing the ball to another player.

Android app UX improvements

Together, these touches brought Plei closer to its ultimate goal: uniting people through the game and helping them find suitable games with joy.

Teamwork That Made It Happen

This project was built on collaboration. We worked closely with full-stack engineers, iOS engineers, QA testers, Plei’s founders and their in-house team. Through daily syncs, shared prototypes, and iterative feedback, we shipped in rapid cycles and learned directly from real users.

Final Whistle

Today, Plei unites thousands of players every week. The Android application is fresh, upgradable, and scalable — and the team feels confident to deploy features with automated tests, modular architecture, and incremental refactoring.

Updating an app isn’t about replacing libraries — it’s about setting the stage for future optimizations to be safer, faster, and better. For us at Krononsoft, helping Plei achieve that has been a rewarding experience.

Sebastian Duque - Co-Founder and CEO of Plei
Sebastian Duque

Co-Founder & CEO of Plei

“Over our nine-year partnership, Krononsoft helped us successfully bring Plei from concept to a fully functional, market-ready platform. Together, we launched and scaled our product to support tens of thousands of users across multiple cities, improved performance and stability over time, and continually expanded feature capabilities.”

Review on Clutch.co
Read success story

Bonus

Check out our infographic for a quick look at how we helped modernize Plei’s Android app for scalability, stability, and a smooth player experience.

App Modernization for a Sports Platform [Infographic]

FAQs: Modernizing Android Apps with Krononsoft

What makes Krononsoft’s Android development approach different?

We combine tried-and-tested architecture patterns (Clean Architecture, MVI) with pragmatic engineering — strict separation of concern, constructor injection for testability, and incremental migration strategies (Compose as well as XML). This results in safer refactors and code that is easier for the customer’s team to maintain in the long run.

How do you ensure high performance in complex apps?

The performance is multi-modal: effective UI, smart data flow, and optimized I/O. Performance gains come from profiling CPU, memory, and rendering hotspots, optimizing list composition, and adding prefetching and incremental loading wherever required. To implement these strategies, we leverage tools such as Jetpack Compose for declarative UI, Kotlin Coroutines and Flow for non-blocking data processing, Paging 3 for handling large lists, and Glide Compose (with proper caching and resizing) for images.

How does Krononsoft approach app reliability and testing?

Testing is part of our workflow. We maintain a testing pyramid: business logic unit tests (JUnit + MockK), Robolectric for JVM UI tests, and Espresso for end-to-end instrumentation tests. CI runs tests and static checks; Crashlytics and structured logging identify runtime issues at production time. We also design code to be DI-friendly to test (constructor injection, factories) so mocks are simple and tests are reliable.

Can Krononsoft improve user experience in existing apps?

Absolutely. We balance functional improvements (payments, offline sync, notifications) against UX glamour: uniform component sets, micro-interactions (Lottie), and performance optimizations so features feel responsive. We prefer incremental UI transitions so changes can ship quickly without high-risk rewrites.

How does Krononsoft deploy features securely?

We use feature flags (e.g., LaunchDarkly) and staged rollouts. Feature flags allow us to activate functionality server-side or for specific user groups, collect metrics, and rollback at a moment's notice if required.

How long does app modernization take?

Timelines vary by scope. Phased, low-risk operation (architecture and test improvements + incremental Compose migration) takes weeks or months based on specific requirements. The largest risk is a rewrite from scratch; we avoid that by shipping incrementally, with feature flags, and by testing with real users.

How to measure success with modernization?

We track both technical and product metrics: crash rate and mean time to recover, test coverage and CI health, release frequency, and user metrics like retention, conversion (bookings), and time-to-first-action. Analytics (Mixpanel, AppsFlyer) in addition to A/B experiments facilitate quantification of product impact.

Why choose Krononsoft for app modernization?

We deliver up-to-date Android experience, hands-on design, and collaborative delivery-focused process. We don't just update libraries — we secure the codebase to edit, minimize user-facing issues, and deliver measurable product improvements.

Want to Modernize Your App?

Breathe new life into your application with Krononsoft’s App Modernization Services. Whether it’s updating tech stacks, migrating to modern architectures, or integrating new features, our engineers ensure your legacy app evolves safely and efficiently.

Talk to experts
Artsemi Nekhai
Artsemi Nekhai

Artsemi Nekhai is an Android Software Engineer passionate about building scalable, high-performance mobile apps. He specializes in clean architecture, Jetpack Compose, and Kotlin Coroutines, focusing on creating smooth, high-performance experiences. Artsemi enjoys crafting maintainable code and collaborating closely with teams to turn complex ideas into elegant mobile solutions.

  • App Modernization
  • Clean Architecture
  • Sports

Post navigation

Previous
Next

Search

Recent posts

  • When should startup hire a CTO
    What to Look for When You Hire a CTO
  • App modernization case study
    How We Transformed a Pickup Soccer Platform into an App for Thousands of Players
  • How to Hire Developers for Your In-House Team

Tags

App Modernization Clean Architecture Code Audit E-Commerce Guides Software Development Sports Startups Tech Leadership Web development

Related posts

Software architecture best practices
Business

How Clean Architecture Impacts Your Business

October 16, 2025 Vadim Kondratiev

Clean software architecture isn’t just a developer’s concern—it’s a business strategy. Learn how technical debt, poor design, and hidden bugs affect profitability, and how a professional code audit can protect and grow your custom software investment.

How build sports technology solutions
Technology

Special Aspects of Multi-Sport App Development

October 14, 2025 Vadim Kondratiev

Building a multi-sport app is more than just adding extra game types — it’s about designing flexible architecture, intuitive scheduling, and payment systems that can handle the unique logic of each sport.

Services

  • Web Development
  • App Development
  • App Modernization
  • Microservices
  • Project Takeover
  • Urgent Help
  • Code Audit
  • Project Analysis
  • CTO as a Service

Company

  • About Us
  • Our Process
  • Technologies
  • Success Stories
  • Blog

Connect

  • LinkedIn
  • Facebook
  • contact@krononsoft.com

© Krononsoft 2014-2025. All Rights Reserved.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

  • Privacy Policy
This website uses cookies for personalization, analytics, and advertising. By continuing to browse, you agree to our use of cookies. See our Privacy Policy for details.