Hi! I’ve had a bit of radio silence for the past few months, but there’s been quite a bit going on. New website, etc. Expect to see a few progress updates in the near future. Thought we’d start with what’s fresh on the mind.
I gave an impromptu overview of this concept yesterday to the Touchlab team. It was a bit of a whiteboard disaster, and probably a little late in the day for sweeping industry concepts. Later, at the Kotlin Meetup, I talked to two different people who kind of immediately got what I was talking about. Context is important I guess.
One of the issues while explaining to the team was, “if this happens … whenever they get around to that”. There are timelines, agendas, and moving parts involved. We have to think forward a bit.
I’m just going to suspend reality here, pretend it’s the early 2020’s, and everything I want the Kotlin team, the mobile community, and the broader industry to do has happened.
It’s the 2020’s!
For the most part, “cross-platform” means taking web ideas and putting them onto mobile. That’s the wrong direction. Sharing code and architecture allows what we’re calling the Mobile Oriented Architecture.
MOA. Yes. Another acronym. You’re welcome.
Just a heads up. We’re talking architecture. Not UI. Not yet, anyway. UI and the features that make native native (notifications, force touch, “the notch”) are important but not part of this discussion¹.
At its most basic, MOA means applying the same code base, using mobile-tested architectural techniques, to deliver whatever client you’d like. Doing this for Android and iOS is trivial. For the web, WebAssembly (and to some degree JS) makes this feasible.
Android and iOS is trivial?
Trivial is a strong word, but the process is straightforward at least. Under the hood, they are basically the same. This was the conclusion of our J2objc/Doppl odyssey (It was also the premise, but I digress).
They are very similar systems: both are unix-y, have threads, sqlite, files, networking, etc. The Android community prefers MV* as an architectural construct. iOS apparently likes VIPER. The point of both is to make code more reliable, testable, and maintainable. The choice of either is community preference and has nothing to do with platform.
Android and iOS can be thought of as simply the “mobile platform” as far as architecture is concerned. That was true way, way back in 2018, assuming you were OK with Java (it’s the 2020’s, remember).
There are, of course, several stacks with which you could implement MOA, but the Kotlin platform is distinct for a number of reasons:
- It is a modern language with excellent tooling.
- On the Android side, it’s fully embraced and “native”, adding zero platform risk or impacting development efficiency.
- The interface between “native” and “shared” is not an exception but a normal and expected part of development (aka. Smooth interoperability). For example, you don’t need to wait for somebody to wrap a library around some new iOS things. You have Swift readily available.
- We’ve managed to convince the iOS community that embracing Kotlin/Native and multiplatform for architecture sharing is a great way to be “mobile first”, as opposed to React Native or whatever. (Again, to highlight, this is the future. Selling iOS folks is on the todo list)
- That same iOS community has done a lot of work creating the truly multiplatform libraries needed to have efficient development.
The iOS community is, I think, one of the critical pieces that made Kotlin MOA feasible. Swift and Kotlin are very similar. Kotlin is obviously “Android leaning”, but not so much as is Java. Because Kotlin/Native doesn’t have the JVM, for better or worse, it forces a more balanced bridge between the two environments. Summary: it’s not just the “Android language”².
Besides just sharing code, there are some interesting consequences of MOA.
When all of your code is in different languages and implemented separately, you tend to have “back end” engineers, and teams focused around the different client platforms. If you‘re implementing lots of client logic with a single code base, the “back end” engineers are going to get involved in the client code that consumes the service they’re building.
Rather than looking at the remote client as this “other” thing, it’s just a remote part of a connected system. For example, imagine a microservice style system with multiple clients. It might look something like this.
But it can look like this.
That’s not just the api call implementations. You could generate them from Swagger or similar. It’s logic, storage, offline, whatever, and all of the associated testing. Doing this in an environment without significant trade-offs with regards to development efficiency, runtime bloat, or risk is the goal.
Sounds like SOA
Sure. The mobile part is how you architect the client side and where web fits in. You’re always offline until your call succeeds. 5G is “better”, but didn’t fix the fact that you’re mobile any more than 4G fixed it. Taking what we as a community have learned from mobile and architecture, putting that together with the teams building the server side to produce mobile-focused api’s, and producing a better functioning unit is what MOA is about. The web inherits the mobile architecture⁴.
Back in 2018
But it’s still 2018
A number of things need to happen between now and then for the Kotlin version of all this to be real.
Kotlin/Native needs to be a fully baked part of the Kotlin multiplatform ecosystem. Around KotlinConf last year we were thinking this would be early 2018, but it’s not quite there yet.
If you follow progress on github, there’s some really cool stuff happening. Read the concurrency doc, for example. If you’re enough of a language nerd to know why Rust’s concurrency is cool, you’ll notice the same concepts. On the downside, reading the doc gives off the vibe that there’s going to be a lot of stuff that only functions in Kotlin/Native. If your thread sync needs to be handled in platform-specific code (and it obviously would be for JS), it’s not the end of the world, but still. Hopefully Kotlin JVM and Native aren’t too dissimilar.
We’ll need Kotlin/Native iOS-friendly libraries. I think there’s a strong pitch to make to the iOS community about why this is something they should get into, but that’ll be a whole different blog post.
We’ll have to see about WebAssembly’s progress as a standard. That’s a much bigger “if/when”. Kotlin/Native already has surprisingly good support (sample) for the current Wasm implementation, but Wasm needs a lot of the things on their post-MVP roadmap to materialize in order to be useful as a general purpose web app architecture. Threads, gc, and solid DOM access for starters. This is the part where the industry as a whole is going to have to deliver. For the suggestion box, it would also be great if we could reconsider Web SQL and make file storage universal. Thanks, industry!
But can’t you do this already with JS?!
Yeah, kind of. There will be multiple platforms from which you can deliver mobile and web. C++ all the things. Ruby for everybody. Dart, I guess. It’s more about the organization of everything. JS frameworks (React, NativeScript, whatever) are generally going to be web-focused. Flutter in its own way is a reaction to React, but this isn’t a JS or Flutter rant, so we’ll move on.
In a bit.
We (Touchlab) just see this next wave of technologies as a better answer for a lot of scenarios. Especially if you’re a large org doing a lot of Java (and there are a lot of those). Outside of just this stack, the more similar web and mobile become, the less different everything needs to be (architecturally speaking, of course).
So, anyway. Keeping an eye out for that multiplatform commit…
¹ So, my UI rant. The short version is, most of the cross-platform stuff is trying to be an “everything” solution. Architecture and UI. Most include some way of interacting with “native” bits, but they’re generally treated very much as an exception. That means you need to make Big Decisions about platform choice. I like little decisions. What to do about more common UI is something we should look at, but the foundations should be poured first.
²There are some concepts to unpack here. J2objc is not something most iOS devs have been excited about largely because it feels kind of like a hand-me-down from the Android side. React Native and everything else that’s JS-based is a hand-me-down from the web. Xamarin, well, you’re either an MS shop or you’re not. I think the iOS community would embrace Kotlin more, largely because there’s going to be a need for iOS-leaning libraries, and until somebody builds a viable Swift for Android, it’s the best opportunity to *not* be in a hand-me-down situation. Mobile teams need a response when management says “what about ____?”, and this is a good one.
³ Don’t get too tripped up on the details. You could write a book on that. I don’t think the “server devs” should ship packages sdk’s to the “front end devs”. There’s a lot of history about how you should and should not do this. If you’re old enough, you’ll remember when Java Enterprise Bean spec tried to dictate separate roles for different parts of your team. Guess they still do? Amazing. Would not recommend. A good write up of implementing code sharing with different team focus can be found in the “Developing & Debugging” section of this blog post from Slack.
⁴ You could make it one big monolithic back-end service, but the mobile part still needs to get done right. Server architecture recommendations today tend to like a lot of little services, so that’s what we put in there, but you don’t *need* to do it that way.