Native HTML Apps with Xamarin

At the tail end of last year, my team was working on an Ember.js app. That would usually be pretty normal, but in this case, it was an Ember app running in Cordova utilizing massive amounts of offline support. We needed to support Android and iOS. Offline support meant downloading most of our users’ data, processing it, and storing it—all while keeping the UI responsive using the single Javascript thread. As the project progressed, it became clear that this tech stack was not going to hold up.

So how did we get to that point? Why Cordova? Well, Cordova is a cross-platform framework for building mobile web apps hosted in a native shell. And our client had an existing Cordova application. To avoid a major rewrite and overhaul of the design, and because we’d worked with Cordova in the past, we went with it.

Pain Train Arrives at the Station

Cordova does a decent job of building apps for both Android and iOS, but there are still a lot of rough edges. Cordova takes a very WebView-centric approach. The main vehicle for any app logic is the JavaScript run-time in the native web view.

In our app, we had to support full offline functionality. We needed to download, process, and store most of our users’ data locally on the device. Even if we used an SQLite plugin to offload the data storage, processing became unbearably slow. Because Cordova is so browser-centric, JavaScript and its one thread are your only option for computation. Any native pieces are mostly bolt-ons that need to be completely implemented in each of the native platforms you wish to support.

Next Stop, Xamarin Town

Using Xamarin with the HybridWebView addressed all of our problems with Cordova:

  • It’s performant; it compiles down to native, supports multiple threads.
  • It’s DRY; it implements most logic in C# with minimal amounts of native code specific to Android or iOS.
  • It gets access to C# and its features (Rx.net, async/await, type checking/inference).
  • It can still use our Ember.js app with very few changes to our JS/HTML/CSS.

What Does the Code Look Like?

Once set up, the interfaces to execute native code and subscribe to observables from JavaScript are quite nice. Here are a couple quick examples and all the code required to set it up on your own Xamarin project.

  public class ExampleServiceObject
    public async Task<Point> GetCoord(JToken someArg)
      // ... native integration / DB look up / etc
      // This will automatically be serailized back as JSON
      return new Point{X = 5, Y = 8};

    public async Task<IObservable<Point>> OnPositionChanged()
      // ...


  import Xamarin from 'my-project/utils/xamarin-interop';

  // direct call
  var p1Point = Xamarin.call('ExampleServiceObject.GetCoord', "player1");

  // subscribe for updates
  this._positionSub = Xamarin.subscribe('ExampleServiceObject.OnPositionChanged',
    point => {
      console.log(point.x, point.y);
  // later on, destroy the subscription when you're done

There is quite a bit of glue needed to make this setup work. There is a sample repo showing how to make this interoperability happen.

So, How’s the Project Doing?

After switching to Xamarin, the application’s performance problems disappeared. We’ve were able to use shared C# code for our new native components in the app, and development and testing became quicker and less frustrating. I’m glad we made the switch, and I’ll continue to use Xamarin for native mobile web apps in the future.