Case Study

MyBSWHealth — Baylor Scott & White

Android Technical Lead & Mobile Developer · July 2016 — January 2019

~10K active users across North and Central Texas.

Xamarin.AndroidKotlinReact NativeTypeScriptSwiftJS BridgeHockeyAppFirebase CrashlyticsVisual Studio App CenterAzure DevOpsSelf-hosted macOS Build AgentsGoogle Play ConsoleC#

A healthcare app that needed more than new features.

MyBSWHealth gives patients of Baylor Scott & White Health a single place to manage their healthcare: appointment scheduling, secure messaging with care teams, lab results, telehealth visits, bill payment, prescription refills, insurance information, and family health management. It covers the patient experience for one of the largest not-for-profit health systems in the United States.

When I joined, the app existed but was in poor shape. It had been built under significant time pressure by a team of highly capable native iOS and Android developers who were simultaneously learning C# and Xamarin. The result was an app that worked but carried serious quality debt, crashes were frequent, performance was rough, and the codebase reflected the conditions it was built under. I was hired specifically as the Xamarin expert to help stabilize and improve it.

Over the next two and a half years I improved the stability of the existing Xamarin app, built the team's CI/CD system from the ground up, became the Android Technical Lead, and eventually led the Android team through a complete rewrite using Kotlin and a hybrid React Native architecture. By the time I left, the crash rate had dropped to under 1%, the Play Store rating had climbed from 3.5 to 4.5 stars, and the team had a clear path toward a fully React Native future.

Diagnosing a crash problem that had many causes.

The crash rate when I arrived was over 300 per day on Android. The underlying causes were not a single bug — they were a pattern of architectural and code quality issues that traced back to the conditions the app was originally built under. The team had built it the way experienced native Java and Objective-C developers would approach a project, which was entirely reasonable given their backgrounds, but Xamarin and C# have different idioms, patterns, and pitfalls:

  • Null reference exceptions
  • Improper lifecycle handling
  • Decisions that worked in native Java but did not translate cleanly to the Xamarin layer

Using HockeyApp for crash reporting at the time, I worked through the stack traces systematically, identifying root causes and prioritizing the ones driving the highest crash volumes. Over roughly a year I brought the crash rate down by 40 to 50 percent on the Xamarin codebase. That moved the numbers, but the depth of the quality debt meant there was a ceiling on how far stabilization alone could take us. The architectural rewrite, when it came, was the right call.

APK size: 40MB down to under 24MB.

The app's APK was over 40MB, which in the earlier days of Android and mobile data speeds was a real barrier to downloads and updates. The bloat had three main sources:

  • Unused image and file resources that had accumulated and were never cleaned up
  • Image assets that were unnecessarily large — in some cases icon files weighing over 1MB that could be rendered at equivalent visual quality at a fraction of that size
  • A release build configuration that was not set up correctly

The team had not fully understood Xamarin's build configurations, so the release build was essentially functioning like a debug build. The linker was not stripping unused code or libraries, and compression was not being applied. Fixing the build configuration alone had an outsized impact on the final APK size.

Working with the UX/UI team to audit and re-export image assets at optimized sizes, removing unused resources, and correctly configuring the release build pipeline brought the APK from over 40MB to under 24MB. Faster downloads, faster startup, and a noticeably lighter install for users.

Building CI/CD where none existed.

When I joined, there was no CI/CD system. Releases were produced manually, one person would build the iOS and Android release artifacts and upload them to the respective app stores by hand. There was no automated build triggered by pull requests, no way for QA to get a build without going through that manual process, and no safety net between a developer merging code and that code reaching a tester.

I introduced Visual Studio App Center as the CI/CD platform for the Xamarin app, working alongside a colleague to set it up. From that point forward, builds were triggered automatically when pull requests were merged, and app store submissions could be kicked off at the push of a button rather than manually assembled. QA could get a build as soon as a feature or fix landed, which changed the pace at which the team could validate and ship.

When the team later rebuilt the app in Kotlin and Swift, we moved to Azure DevOps Pipelines. At the time, Azure DevOps did not support macOS hosted build agents, which posed a problem since iOS and Android builds both required macOS. The iOS Tech Lead and I solved this by procuring Mac Minis and configuring them as self-hosted Azure DevOps build agents. We installed the official agent software, connected them to our Azure DevOps instance, and they became our macOS build infrastructure from that point forward.

The architectural pivot: native plus React Native, one app.

About a year into my tenure, the team reached a decision point. The existing Xamarin app had improved significantly, but the consensus was that stabilization had taken us as far as it could. The decision was made to rebuild both the iOS and Android apps natively, using Swift and Kotlin respectively, while incorporating React Native for the main dashboard and selected screens.

The hybrid model was a deliberate architectural choice, not a compromise. The team had seen the benefits of shared cross-platform code firsthand, and React Native offered a way to get those benefits for the right parts of the app while keeping native performance and platform fidelity where it mattered most. The main dashboard was the natural candidate for React Native, with a clear path to migrate additional screens over time.

The technical challenge was making React Native and native code genuinely interoperate. We used the React Native JavaScript bridge, which at the time was how React Native itself communicated between JavaScript and native layers underneath the hood. It functioned as a message broker: the TypeScript side could send serialized JSON commands to the native side, receive responses back, and React Native components could be embedded directly into native screens. Because we were working with the same mechanism React Native used internally, it was well-understood, extensible, and reliable. The integration required research and experimentation, but there were no major blockers. It worked.

I was selected to lead the Android team through this effort — a team of five on-site and three offshore developers. My responsibilities covered:

  • Architecture decisions
  • Code quality standards
  • Cross-team coordination with QA and UI/UX
  • Google Play management throughout
A pure React Native app is essentially a small native host that runs the JS runtime. We just flipped the ratio. Our app was mostly native, hosting React Native where it made sense. If React Native ever proved non-viable, we could replace those screens natively and still be in a solid position.

What two and a half years of focused work actually produced.

300+/day

Android crash rate when I arrived

<1%

Android crash rate when I left

3.5 to 4.5

Google Play rating improvement

40MB to 24MB

APK size reduction

The app was faster, more stable, and the UI had been updated along with the rewrite. The team had a clear path to a fully React Native future, which they have since completed. BSW leadership took notice, which was gratifying, but the more important outcome was leaving behind a codebase the team could actually move in.

I left to return to Quisitive when the opportunity came back around, partly because Cinemark had specifically asked for me. I left the BSW team in a strong position, with a solid app, a capable team, working CI/CD infrastructure, and a roadmap already in motion.

Technologies used

KotlinReact NativeTypeScriptSwiftXamarin.AndroidC#JS BridgeHockeyAppFirebase CrashlyticsVisual Studio App CenterAzure DevOpsGoogle Play Console
← All case studies
Not actively looking

Let's have a conversation.

I'm not actively in the market right now, but I'm always open to conversations worth having. If something here caught your attention, I'd still like to hear from you.