Transitioning from Titanium to Flutter: a technical summary
Axway, the company that supports and develops the cross-platform mobile development platform Titanium, has recently announced that it will no longer support the software past March 1, 2022 and will close down Axway Cloud Services from September 1, 2022. This article considers other options for future development for individuals and companies that currently use Titanium, who may be looking for alternatives, with a focus on my personal experiences transitioning from Titanium to Flutter. For Axway Cloud Services there is no question that an alternative has to be found. I never rated this service and never recommended it for any clients, but I have had to use it on inherited projects where it was painful to do so because of numerous bugs (and that was just notifications). There are obviously many alternatives for backend services, but I won’t cover that in this article.
Titanium was one of the first cross-platform frameworks and, arguably, was the best for a period of several years in the 2010’s. There are lots of reasons as to why this new development has happened — political, market force led and technical — but I am not going to go over these here. My former colleague, Angus Fox, has written a very good article on LinkedIn summarising the history of both Titanium and Flutter and how this might affect business decisions as to which platform to use for ongoing work. There has already been a heated debate on TiSlack on how to transition Titanium to a supported, open-sourced framework and I am confident that this will happen in the long run, but my personal view is that this is not viable long-term due to: the incessant speed that the underlying native iOS and Android platforms progress; the fact that very few people actually use Titanium at the moment (and this will be greatly reduced now, as people move away to other frameworks); and it will always be difficult keeping up with new OS versions, changes and additional functionality (that has not even been invented yet). Certainly, for an enterprise organisation or even modest sized SME, long term reliable and timely support and maintenance backed by a solid partner is crucial. I, through my company Icecandy, have used Titanium since 2011 and have relied on it to produce great, high-quality, cross-platform apps for various clients, In my business I find it essential to be able to offer iOS and Android versions of apps. I have loved using Titanium and will still carry on using it as long as it is viable to support existing apps. It is, and has been, one of the best cross-platform frameworks. However, I think Flutter is the newer, superior, technology and over time will become the leading cross-platform solution. From now on I will be building most new projects with Flutter. Flutter not only supports mobile, but also web, desktop and in the future, I am sure, other IOT and connected device platforms (it’s an interesting side-note that when Titanium started it too had aspirations to support web and desktop, but these are incredibly resource hungry objectives and, for Titanium, they fell by the wayside). Flutter is backed and developed by Google and in my opinion — without getting into flame wars about Facebook v Google v anyone else — is going to be around for a long time. Other options include: React Native, Xamarin, Native Script, Ionic and other web app solutions. React Native is the only viable alternative in my opinion, but I didn’t transition to that when it became the most popular framework a few years ago because it is very similar to Titanium, whilst at the same time is not so good or performant (I am not an expert in React Native, but I have used it and followed the community closely). None of the other frameworks mentioned come close to a complete native experience or functionality, which is the holy grail for cross-platform frameworks. Flutter, on the other hand, takes a very different approach to Titanium and React Native, which has distinct advantages, but also a partial disadvantage. Both Titanium and React Native allow you to write code in Javascript, mixing in SDK calls (either through code or markup languages like Alloy XML — for Titanium — or JSX — for React Native) which transpile to native code and OS based frameworks (Objective-C/Swift on iOS or Java/Kotlin on Android). This has the advantage that you use the underlying native framework for the UI of your app so you get a truly native UX experience. The drawback is that the business logic — which stays in the Javascript world — has to bridge back and forth to the native world to communicate. This can produce bottlenecks and in the past I have seen this to be a real performance hog in Titanium and React Native. Admittedly, if written properly with good coding practices, this is rarely a problem in modern apps on either platform. Most of the time, you don’t expect to get 100% of the performance of native, but it is so close as to not be discernible. However, trying to do something that requires high performance, in particular graphics, like a 2D game — or even just a fancy screen transition — will show this up (some years ago a games framework to solve this problem was created called Platino, which worked with Titanium, but never took off).
Flutter, in contrast, by-passes the underlying OS for UI creation completely, drawing everything low-level with its own engine. On mobile this is done with Skia, a C++ based 2D graphics library. On web, javascript (transpiled from Dart, which is used by Flutter) is used to draw directly to an HTML canvas. For mobile, this produces highly performant execution even to the level of being able to produce 2D games (see for example SpriteWidget or flame). On Android, Flutter even competes well with native coding and seems to perform well across the large Android footprint of devices and OS versions. There is no “bridge” bottleneck and graphically one can create any sort of UX conceivable. In this respect, it reminds me of Flash and ActionScript 3, which I used back in the day, to produce seamless, animated rich media, web and desktop experiences.
As Flutter is backed by Google it is first and foremost a Material Design framework. This means it is naturally, out-of-the-box, predisposed for Android development. Material design can, of course, be used on iOS, but it is not the native Apple look and feel. The drawback, on iOS, is that the UI is drawn by Flutter. A whole set of SDK calls — prefixed by “Cupertino” — exist to emulate the look and feel of iOS. But they are written by the Flutter engineers and are not an exact copy, although they are very close (you can probably talk to any graphic designer to back me up on this). Also, not all the native iOS UX is covered, although probably will be eventually. Now, I am a designer and UX specialist, as well as being a developer, and so this does hurt my aesthetic sensibilities, but at the end of the day I am not sure the end client is bothered much by this. As well as this, iOS and Android consistently seem to copy from each other. An example is that the “…” Menu was never standard on iOS, but was and is in Android Material Design. This is now supported and used in quite a few apps on iOS. So if you can live with this disadvantage, then Flutter will be a perfect solution. Otherwise, one should consider React Native. My main overriding persuasive point going for Flutter is the extended platform support for web and desktop. The web support has only just reached a stable version and does, from my experience, suffer from a lot of problems still. It doesn’t compete at all with sites built with any modern framework — such as React, Angular or Vue — yet, but could in the future.
Enough of the summary, how about some details? Well the next overriding main difference between Titanium/ReactNative and Flutter, is that Flutter uses Dart as the main coding language, rather than Javascript. Dart is a typed language which I love (having a background in C and ActionScript), although people have their preferences. More akin to TypeScript and ES6, it fills a few of the holes that Javascript has (eg just uses null, rather than undefined and null) and has lots of built in support, which is additional to core Javascript, such as Promises (called Futures in Dart) and Underscore-like functionality. I find it a joy to work with and picking it up was pretty quick. The compiler is great and debugging is enlightening.
Now a list of assorted differences I have found between using Titanium and Flutter/Dart.
Ease of Coding
Flutter is slightly harder to use than Titanium. It takes a while to get your head around the state model they use rather than the imperative programming style used in Titanium — React Native is somewhere in-between the two. Flutter works by composition of widgets, where everything is a widget (even UI event listeners). But once you get it and learn the paradigms, on the whole you can do things quicker and more efficiently than in Titanium or React Native as there is so much ready-made boiler plate. For example, loading dynamic data in a list or table view can be done with just one base widget (such as a FutureBuilder or variations of the basic scrolling views). No need to add listeners and get involved with Alloy’s Backbone syncing as one does in Titanium.
Style and MVC Differences
In Flutter everything is controller code, so no separation of views and styling as in Alloy XML/TSS. I must admit I miss this as I do love Alloy (there is regular discussion online about this in Flutter and so it is perfectly possible this may come in the future). Base flutter doesn’t have an underlying MVC framework, although you can create your own. Regular flutter code can be a bit verbose sometimes with nesting widget nightmares, but editing in Visual Studio is a delight with fantastic auto-formatting and completion etc (Android Studio offers good support for Flutter too, but I haven’t used it).
Hot Reload
“Hot reload” works really well in Flutter and is super fast. In the early days using Titanium I, and most people, used TiShadow for hot reloading, but it was very temperamental. Lately Titanium LiveView works well. Flutter’s setup can be temperamental too, but when it is setup and working it is really fast.
Tooling
Flutter is easy to setup and install. There is an issue with version support, as by default one can’t easily switch between versions of the SDK or use different versions for different projects. However, fvm (Flutter Version Manager ) does support this and I have found it to be invaluable. I have had a nightmare updating older downloaded example projects because of iOS native incompatibilities, which is a known problem with Flutter. Flutter works really well with Visual Studio. Titanium tooling/building breaks almost always upon SDK or Xcode version upgrades, but Titanium also works well with Visual Studio and so there isn’t much difference overall on balance. There are some super new tools that have just been announced with Flutter 2.0, but I’ll leave you to research that.
Learning
There are fantastic learning resources for flutter. The official documentation is comprehensive and solid. There are tons of Udemy courses, posts and general online discussion. Titanium over the years has had very sporadic and random support. The official documentation has always been under par, with not a lot of real world examples (apart from a few great books which are, as with all software, now out of date). There is a Flutter Slack group, but overwhelming in the number of people and channels on there and so I haven’t used it so much. Nothing to match the fantastic, but small, niche group that we Titanium users are that can be found at TiSlack.
Coverage
Flutter mobile is not fully complete yet, especially for iOS (at least it is in general coverage, but some of the individual bits or widget properties aren’t fully comprehensive yet). An example I came across is video playback support, where not all native functionality is supported yet. Some people have mentioned Maps as a problem. The Google Maps plugin (Flutter calls its modules packages or plugins) is in version 2.0 now and has been around for more than 2 years. I haven’t used maps yet so can’t say exactly. I am using a 3rd party web view package InAppWebView which is great. If it isn’t fully supported by core Flutter there is likely a 3rd party library to fulfil any requirements. There is a huge community of third party packages and at the latest count — advertised at Flutter Engage — there are more than 15,000. For example, I found a great package (in fact two) to create dynamic PDFs in-app, which I haven’t been able to find for Titanium. Core Flutter development is steady and over time it will reach full native parity (remember Flutter is only 2 years out of version 1, whereas Titanium has been around since before 2010).
Plugins
I haven’t tried to write a native plugin for Flutter yet, but it seems that it isn’t too difficult — see here for more details. Titanium has a mixed bag of plugins which are often out of date or barely supported and if one doesn’t exist it is sometimes difficult to find someone to write one. Titanium’s hyperloop for me has been so inconsistent and lacking in support and documentation that it never was an advantage. I am not a native developer and so rely on 3rd party modules or hiring native developers to implement specialised functionality.
Firebase
Firebase integrates really well with Flutter and is very easy to code in an app and generally easy to use as a backend service. Probably as they are both from Google! Titanium, on the other hand, still does not have a full suite of firebase modules (no cloud file storage or firestore for Android) and it is not officially supported by Axway (not that that will matter moving forward).
Assorted Components
- Text and TextFields
Flutter’s Text and TextField widgets are more comprehensive than Titanium one’s. They support more styling out-of-the-box, although one can always reproduce this in Titanium by creating Titanium custom Widgets. Forms likewise have a bit more cladding. Flutter Text widgets at their base level are composed of pure Rich Text widgets and so are very configurable and styling text, with accurate font metrics (using advanced features such as ligature control, for example), is really easy and much more powerful than with Titanium. - Navigation
Navigation is a strange one in Flutter. Titanium navigation has always been really easy with smooth native-performance transitions and support — on iOS especially — for the standard Navigation Window and Tab Group hierarchies. Basic navigation is also easy in Flutter, with super smooth transitions, but you have to create more boiler plate (not so much) to do transitions and there are automatic platform specific transitions, but again on iOS they are emulated and not 100% the same . Also, the standard hierarchies are not supported so well (Tab Group’s are supported, but a little fiddly, and Navigation Window’s don’t easily collapse to the root). Flutter basic navigation has problems such as supporting the Android back button fully and managing a complex stack of windows. A new version, Navigator 2.0, has been developed to deal with these issues, but there is a huge amount of dissent and complaints in the community about how complex the Flutter dev team have made it. The complication is that, for Flutter, navigation has to apply to the web (supporting things like the back and forwards browser navigation buttons) as well as mobile and other platforms. An annoying side-effect is that everything is couched in terms of the very web-centric “routes” and “pages”, rather than screens or windows, but that is a minor grouch. - Theming
Theming in Flutter is completely Material Design centric. A lot of theme properties in Material Design are quite obscure and so unless you are from a native Android background and used to using Material Design it can be quite confusing. Also, theming is not iOS friendly, so I roll my own theming for colours and styles. One example are buttons, where I hate the ink well effect on Android/Material Design and prefer the simpler iOS version of button states and so I choose to roll my own for that too. - General Layout
Layout with both frameworks is pretty straightforward. Flutter has a vast array of layout widgets to help with this such as Row, Column, ListView, Grid and many others. The weird thing, coming from a Titanium background, is that to align an object in some way, instead of setting that as a property (such as left, right, top and bottom) in Flutter you have to nest child widgets in an “aligning” widget. Even padding often requires nesting the widget you want to pad inside a Padding widget. With Titanium it is obviously easier to see layouts schematically in an Alloy view, although you can always examine the Flutter widget tree. Flutter can be a bit more frustrating than Titanium as far as overflowing widgets are concerned, which it shows graphically as an error on screen, but often is difficult to work out why there are issues. - App Config.
App configuration is easier with Titanium. There is no single file where specific iOS or Android native config can be done, as there is with tiapp.xml (for example Info.plist properties for iOS or Android manifest settings). The config for Flutter has to be done in the respective iOS or Android template projects. - State Management
Flutter doesn’t do much state management out-of-the-box, but if you want to get more sophisticated there are numerous packages that offer this such as Bloc. State management in Flutter is designed to manage state in a series or stack of widgets. It is more similar to React Native in concept. In all my time using Titanium I never needed any very sophisticated state management, managing with data models and libs and passing data between modules. Backbone handles some of that for you with model and collection syncing. - Events
Events in Flutter are in some ways much more complex, and in some ways much simpler, to use than in Titanium. Events in Flutter are handled by Dart Streams, which are a much more sophisticated model of a sequence of events. Rarely does one use a simple event listener, although some widgets do take an event listener handler as a property. Streams can be complex to grasp and use, although in practice you don’t often have to manipulate them directly and you might do something like pass a stream that a data loader supplies into a ListView, for example. All the complex, background, creating and responding to events is hidden from you.
Well I hope that this article has helped in making a decision as to what to do regarding the future “decommissioning” of Titanium. I believe Flutter is an exceptionally good alternative. At the end of the day no framework is perfect and there are always compromises. You may choose to stick with investing in the Titanium open source movement, but personally I think that is a risky bet (although I certainly will support it moving forward). If anyone would like advice or help in porting their Titanium apps to Flutter please get in touch.
Simon Buckingham is a designer, UX specialist, animator, creative and technical director and developer with more than 20 years experience. He has been making cross-platform iOS/Android mobile apps with Titanium, and more recently Flutter, for more than 10 years. Simon runs his own company Icecandy, based in Winchester, UK. You can find out more about his digital career at simonbuckingham.me.