Strada is an optional add-on for Turbo Native apps that enables native components driven by the web. It unlocks progressive enhancement of individual controls without converting entire screens to native.
For example, converting a <button> to a UIBarButtonItem on iOS or rendering a HTML modal with ModalBottomSheetLayout on Android.
It’s important to call out that Strada alone doesn’t unlock new features for Turbo Native apps. Everything you can do with the framework you could already do before. Albeit with much, much more code.
Strada provides structure and organization to the tangled mess that is the JavaScript bridge. It simplifies and standardizes communication between web and native components, which makes building robust native elements a joy.
Just my 2¢, having worked with Turbo Native for 6+ years now.
This isn't a React Native Web like approach where you try to cover the same surface area, but rather an individual implementation of each screen, so you could tweak and modify it for the given platform if needed?
Is it possible to embed native controls inside a webview or does this approach only work top down, i.e. does a components parent need to be native for it to be possible to be rendered natively?
You get baseline HTML coverage for free – Strada makes it easier to make things a bit more native.
I only read three emails newsletters, and Joe’s is one of them because it’s roughly once per month and it keeps me current on all the things happening with Hotwire and Turbo Native apps.
I'm writing up my thoughts on the Strada launch right now. It will hit my newsletter, blog, and RSS feed tomorrow morning.
tl;dr - Strada alone doesn’t unlock new features for Turbo Native apps. Everything you can do with the framework you could already do before. Albeit with much, much more code. Strada provides structure and organization to the tangled mess that is the JavaScript bridge.
We've been doing a similar pattern already, because we have our web app iframed and communicating with outlook (via Office.JS) and gmail (via InboxSDK.JS) in order to read changes to the To: field and insert contents into the compose page based on that:
* stimulus encapsulates the javascript logic that "bridges" to Outlook and Gmail, including initializing the To: field listener * stimulus actions can trigger the "bridge" as well
It's worked out very well - though I really hate dealing with native stuff in general - especially compatibility nightmares with older versions of Outlook. Probably less of a problem with iOS/Android.
Finally!
You make a web server that returns JSON defining your UI. Then you make a native iOS app by copy/pasting the provided Main.swift file and adding the URL of your server. The app uses an iOS client library, fetches the JSON page definition, and builds/updates the page with native widgets. I'm planning to eventually build Android, web, and desktop clients.
I agree with the sentiment that Android is just such a years long train wreck. I am currently rewriting one of the Android apps in 100% (as much as possible) "modern" and @Compose Android. So far... it seems better. But maybe the newness will eventually wear off. Some will the credit the "paradigm", but UIKit demonstrated to me that you could be a solidish "OO" ADK. I attribute @Compose to just being better engineered as a quasi functional approach than Android original stuff ever was as a Java implementation.
I am so worn out with the overall approach though. It is a ton of duplicate work. But I despair that the alternative would be no better? It seems that while today, I duplicate a lot of work, I get to choose how complex and coupled the various layers are. I do my best to just use stock stuff and not mash a bunch of stuff in. With a "web tech" solution, it seems the duplicity just rotates, so that the duplicity is just replaced by the complexity of trying to coordinate lots of disparate technologies, having to grow versed in even more domains, so that intelligent assesments can be made when things don't work as expected, and in which bucket/layer to focus ones efforts for each feature.
All that said, would you still encourage me to do as as you've done? I am honestly open.
It's a really cool pattern to have server-side rendering drive a specification that's used by web and native components alike. Airbnb uses this pattern to great effect: https://medium.com/airbnb-engineering/a-deep-dive-into-airbn... - and ironically, they speak to the importance of strong typing of the data model as a way to control complexity.
I really hoped that Turbo would be a way to make this pattern more mainstream. But, much like Unity, 37signals seems intent on taking actions that hurt its developer community, and it's hard to justify moving towards a solution with such antagonistic governance.
Turbo is free and open-source. Nothing stops people from forking and keeping TypeScript alive in the fork.
I am quite hesitant to use 37signals tools for now. Partially because they pretty much didn't ask anyone dropping TypeScript. But also because in general open source software owned by one single company sometimes goes to the direction community of engineers don't want them to go.
For example, Tensorflow dropped Windows support. While it's Apache License 2.0, and alternatives, there are dependencies.
Do I want to introduce dependency that I will regret in the future? With 37signals the answer is most likely yes. The same for Unity, for example. Or Unreal engine -- even though they didn't do anything wrong... yet.
37signals do not value their reputation too much as well. After mass exodus I expected them too be a bit nicer. But TypeScript situation just tells me it's ongoing issue, there is element of surprise.
I will be happy to know I am wrong, since the tool itself looks like I want to use it.