Developing mobile apps is hard. As a developer, you have to learn a disparate set of development environments and languages if you want to deploy a single app to multiple platforms. Fortunately, frameworks such as Xamarin and NativeScript allow developers to target multiple mobile operating systems (namely iOS and Android) while still using a programming language that they already know.
The big question for the developer then becomes, "Which of these products should I choose?".
In the case of Progress, the question really boils down to whether or not we recommend developers use Xamarin, or our own cross-platform mobile development runtime called NativeScript. While Progress builds and supports NativeScript, we also build UI components for Xamarin, just as we do for all major Microsoft UI platforms. That might seem a bit odd considering that Xamarin and NativeScript could be seen as competing products. One is owned by Microsoft; the other is owned by us. It would make logical sense that we would want developers to use our framework and not those of another company.
First off - we definitely want that. We truly believe that NativeScript is the best solution for building cross-platform native applications.
But we also realize that there is not one right solution for every developer on the planet. Xamarin will be the right solution for some developers, while others will choose NativeScript, and still others will choose different solutions. In order to make it easier to pick the “right solution” for you, your team and your project, we'll break down the differences between Xamarin and NativeScript. First we'll start with a brief description of what each project says about itself, and then we'll get into the technical details.
NativeScript is how you build cross-platform, native iOS and Android apps without web views. Use Angular, TypeScript or modern JavaScript to get truly native UI and performance while sharing skills and code with the web. Get 100% access to native APIs via JavaScript and reuse of packages from NPM, CocoaPods and Gradle. Open sourced and backed by Progress.
With a C#-shared codebase, developers can use Xamarin tools to write native Android, iOS, and Windows apps with native user interfaces and share code across multiple platforms. Over 1 million developers use Xamarin's products in more than 120 countries around the world as of May 2015.
Xamarin was purchased by Microsoft in March of 2016.
Both NativeScript and Xamarin produce Truly Native mobile applications. Truly Native means that all of the UI is composed of native UI controls and all of the underlying device APIs are accessible.
The most important thing to know about NativeScript and Xamarin in this regard, is they do not use a web view like Cordova (PhoneGap). There are a lot of frameworks out there claiming to allow the creation of native mobile apps using web technologies. The way that these frameworks work is to leverage the Cordova project which wraps your application in a browser with no URL bar or controls. The developer then builds the application as a web site, but it is packaged and looks like a native app on the device with limited native API access. In the end though, it is a just a mobile website that looks like a native application. This is commonly referred to as a "Hybrid App".
Web apps are somewhat notorious for performance issues on mobile devices. This is due to the fact that the mobile browser is intentionally limited in its access to device resources and sandboxed from native APIs to ensure battery performance and device security. Hybrid apps inherit all of these performance issues. As one of the original hybrid tools providers, we learned the hard way that it is still very difficult to build a performant cross-platform hybrid application; especially if you want that “consumer grade” experience.
Below is the NativeScript Showcase application running on iOS and Android. You can see the complex animations happening and the UI never stutters. This is the power of truly native mobile apps.
You can install this application on iOS or Android to see how it looks and preforms on your own device.
First let's look at how NativeScript creates the user interface, or visible portion of the application.
As a developer, you create XML-based markup files to build up the user interface. NativeScript then parses that and creates the corresponding native controls. Take the following simple form interface:
Here is the XML that is used to construct that interface in NativeScript:
<
Page
xmlns
=
"http://schemas.nativescript.org/tns.xsd"
>
<
StackLayout
>
<
StackLayout
class
=
"form form-inset"
>
<
StackLayout
class
=
"form-item"
>
<
Label
text
=
"First Name"
class
=
"input-Label"
/>
<
TextField
hint
=
"First Name"
class
=
"input"
/>
</
StackLayout
>
<
StackLayout
class
=
"hr"
/>
<
StackLayout
class
=
"form-item"
>
<
Label
text
=
"Last Name"
class
=
"input-Label"
/>
<
TextField
hint
=
"Last Name"
class
=
"input"
/>
</
StackLayout
>
<
StackLayout
class
=
"hr"
/>
<
StackLayout
class
=
"form-item"
>
<
Label
text
=
"Comments"
class
=
"input-Label"
/>
<
TextField
hint
=
"Comments"
class
=
"input"
/>
</
StackLayout
>
</
StackLayout
>
<
StackLayout
class
=
"padding"
>
<
Button
text
=
"Submit"
class
=
"button button-accent"
/>
</
StackLayout
>
</
StackLayout
>
</
Page
>
All of the application programming is done with TypeScript. That means that when a control executes an event, or some action such as an HTTP call is made, that logic is programmed with TypeScript.
Each of the XML pages has a TypeScript file of the same name that NativeScript will look for. The developer can then use a binding syntax to bind control events in the XML to functions in the corresponding ts (or js) file of the same name. For instance, if the button above was going to submit an HTTP request when it was clicked, it might look something like this...
main-page.xml<
Button
text
=
"Submit"
class
=
"button button-accent"
tap=”{{ submitForm }}” />
import http from
'http'
;
function
submitForm() {
http.post(url,
function
(response) {
// handle response from login service
})
}
The same way that JavaScript can create, customize and interact with any browser API or UI element when used with a standard web browser, NativeScript uses JavaScript to create, customize and interact with any native API or UI element.
NativeScript supports subset of standard CSS for styling applications. This would be the same CSS syntax that would be written for the web. If you were looking closely at the XML example for the form above, you might see the `class` attribute just as you would in HTML. Here is the CSS that styles the form example above.
.action-bar-light {
background-color
:
#ffffff
;
color
:
#FF404B
;
}
.button {
padding
:
10
12
10
10
;
min-width
:
52
;
border-radius:
2
;
}
.button-accent {
background-color
:
#FF404B
;
color
:
#ffffff
;
border-color
:
#FF404B
;
border-width
:
1
;
}
.form {
margin
:
0
0
20
0
;
padding
:
0
;
}
.form .button {
margin
:
0
0
0
10
;
padding
:
0
;
}
.form .form-item {
padding
:
10
16
10
16
;
}
.form .input {
padding-top
:
2
; }
.form .input-label {
font-size
:
18
;
padding
:
4
0
5
0
;
color
:
#444
;
}
.form-
inset
{
margin
:
10
;
border-width
:
1
;
border-color
:
#DDDDDD
;
}
textfield {
font-size
:
14
;
}
.padding {
padding
:
10
;
}
.hr {
height
:
1
;
background-color
:
#CDCDCD
;
}
Xamarin provides two different ways to build applications. Using Native Xamarin, a developer can target iOS and Android in separate projects. Since many developers want to target multiple operating systems with the same project, though, Xamarin provides a framework called Xamarin.Forms for this very purpose. Xamarin.Forms is what we extend with the UI for Xamarin controls. Note, though, that UI for Xamarin from Telerik is available for plain Xamarin as well.
For the purposes of this article, we will only focus on Xamarin.Forms, since that technology is most closely associated with NativeScript in that a single project can be used to target multiple platforms. It is also clear that Xamarin views its Forms functionality as the future of the Xamarin product.
Xamarin.Forms parses an XML based markup language commonly referred to as XAML. In accordance with XAML, most styling is done via resources. Some of the styles will be page based, and some will be global.
Here is the XAML that is used to create that simple form in Xamarin. In this simple example I chose to use page-based styles.
<?xml version=
"1.0"
encoding=
"utf-8"
?>
<ContentPage xmlns=
"http://xamarin.com/schemas/2014/forms"
xmlns:x=
"http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:
local
=
"clr-namespace:XamarinTests"
x:Class=
"XamarinTests.XamarinTestsPage"
>
<Frame>
<Label Text=
"Inset Form"
TextColor=
"Red"
></Label>
<StackLayout HorizontalOptions=
"FillAndExpand"
VerticalOptions=
"FillAndExpand"
Orientation=
"Vertical"
WidthRequest=
"20"
HeightRequest=
"20"
>
<StackLayout Orientation=
"Vertical"
Padding=
"10"
>
<Label Text=
"First Name"
/>
<Entry Placeholder=
"Enter Your First Name"
/>
</StackLayout>
<StackLayout Orientation=
"Vertical"
Padding=
"10"
>
<Label Text=
"Last Name"
/>
<Entry Placeholder=
"Enter Your Last Name"
/>
</StackLayout>
<StackLayout Orientation=
"Vertical"
Padding=
"10"
>
<Label Text=
"Email"
/>
<Entry Placeholder=
"Enter Youe Email Address"
/>
</StackLayout>
<Button Text=
"Submit"
BackgroundColor=
"Red"
TextColor=
"White"
></Button>
</StackLayout>
</Frame>
</ContentPage>
Note that there is no action bar or border in the Xamarin example. This is because neither of those things are possible with XAML. Both require either extending a class or adding items via C#.
All of the application logic in Xamarin is programmed using C#, but because it is compiled ahead of time and not just in time, there are some limitations to what is supported. For instance, Generics are only partially supported in Xamarin when subclassing NSObject. There are also limitations on what .NET assemblies can be used. Just like NativeScript, Xamarin XAML pages have a corresponding XML file where you can program view logic. Since Xamarin implements a full MVVM (explained later) model, the following code might be used to handle a button click in the above form example.
MainPage.xaml<
Button
text=”Submit” Command=”{{ Binding SubmitCommand }}”></
Button
>
class
MainViewModel : INotifyPropertyChanged {
public
event
PropertyChangedEventHandler PropertyChanged;
public
MainViewModel() {
this
.SubmitCommand =
new
Command((nothing) => {
// submit the form
});
}
public
ICommand SubmitCommand {
protected
set
;
get
; }
}
Now that we understand how these two different frameworks actually function, let's get into a more granular comparison or the two frameworks that takes into account more of the development lifecycle.
With Xamarin, developers use C#. With NativeScript, it is TypeScript (JavaScript, CoffeeScript, Babel, etc). That is the major difference between the two. Developers who are comfortable using C# and .NET will generally prefer Xamarin. Those who are more comfortable writing TypeScript or JavaScript will prefer NativeScript.
Thanks to TypeScript, many C# developers have begun to branch out into complex JavaScript applications. TypeScript turns the otherwise very loose JavaScript language into an object-oriented and strongly typed language that allows developers to adhere to best practices while leveraging the “run anywhere” power of JavaScript on both the web and mobile applications.
For Windows users, Xamarin uses Visual Studio (Windows) and Visual Studio for Mac.
NativeScript, as an open-source project, favors the cross-platform Visual Studio Code editor, however Visual Studio integration is provided via a commercial extension from Progress called Telerik Platform. The NativeScript CLI technically allows for development in any IDE, including Atom, WebStorm, Sublime Text 2, among others.
Xamarin supports building mobile apps for iOS, Android, Windows Phone, Windows Universal and Windows 10.
NativeScript supports iOS and Android, and we have started work on Windows 10 support as well.
NativeScript has zero-day support for new operating systems. That means that on the day that a new operating system is available, NativeScript already supports it. This is because NativeScript is simply executing JavaScript on the underlying native operating system, and our reflection-based metadata can quickly be regenerated to expose new native APIs.
Xamarin requires a release to support new operating systems and APIs . This is because Xamarin developers have to create maps and shims for those APIs on top of the runtime. More often than not, Xamarin has this release ready on day 0.
When we say “design time”, we are referring to the time at which a developer is actually building the application.
Since NativeScript is actually shipping the JavaScript that you write, it is able to update applications in real time as you save files without having to rebuild the application. We refer to this as “LiveSync”.
Xamarin apps must be rebuilt in their entirety every time a change is made in order to see the changes reflected in an emulator. In this example, I notice that a word is misspelled and I fix the error.
Xamarin does have a visual designer built into their tools. The visual previews are static. Interactivity has to be tested on the device or in the emulator as with NativeScript.
Both NativeScript and Xamarin support building Android applications on Windows. They also both support building directly to iOS on a Mac. Due to the fact that Apple has restricted the building of iOS applications to a macOS machine, neither NativeScript nor Xamarin can build iOS apps directly on Windows. However, there are solutions provided by both frameworks for this issue.
While iOS apps can be coded with Xamarin on a Windows machine, Xamarin requires ssh access to a macOS machine in order to do the actual build for iOS. There is no way around this. With Xamarin, the developer must have access to a Mac to build iOS binaries.
In the case of NativeScript, the AppBuilder extension from Telerik provides a cloud build service that does not require the developer to own a Mac. This is essentially a networked Mac that we own and provide to developers as a service. The developer then builds on the Windows machine, the code is compiled on our servers and sent back to you in IPA format, ready to be installed on iOS.
NativeScript also provides companion applications that can be downloaded from the iOS and Android app stores. These companion apps allow developers to load their applications on their devices without actually installing them. This is very helpful during the development process.
It's important to note that in the case of iOS, Xamarin does not generate an Xcode project. NativeScript does generate a full Xcode project, enabling full access to the raw iOS project at design time if needed.
Both Xamarin and NativeScript provide a rich step-debugging experience. Xamarin provides debugging through Visual Studio as well as Xamarin Studio. Xamarin also provides a performance profiler. NativeScript provides an extension for Visual Studio Code as well as the Telerik Platform extension for Visual Studio which provides the same step debugging functionality inside of Visual Studio.
You can watch this video for a preview of what debugging NativeScript applications in Visual Studio Code looks like.
Since NativeScript actually creates full iOS and Android projects as part of the build process, the native Android and iOS profiling tools can be used.
Depending on how applications are built with Xamarin, performance comparison will differ. However, since both of these framework produce native applications, the performance is usually ~60 frames per second. That means that there is no perceptible speed issue.
The way that we measure performance goes much deeper than what the human eye can perceive. There are some areas where Xamarin is faster (startup time) and some where NativeScript is faster (GPU usage and memory).
For instance, here are the benchmarks for measuring startup time for a blank app with a single button. Startup time is defined as the amount of time after a user launches the application before they see the first screen.
Platform | Run 1 | Run 2 | Run 3 |
Native | 111ms | 105ms | 108ms |
Xamarin.Forms | 484ms | 471ms | 469ms |
NativeScript | 674ms | 672ms | 670ms |
In these tests, you can see that Xamarin is roughly 200 ms faster than NativeScript at startup time.
Another important benchmark is how fast each of these frameworks are able to perform “marshalling”. this means that when you create a string or integer in C#, how long does it take for Xamarin to actually create that string on the underlying operating system. How long does it take NativeScript to do the same with JavaScript? We refer to this as “marshaling”.
You can see from the table below that NativeScript is significantly faster as marshaling JavaScript to native code. This is one NativeScript's core focuses - to be the fastest runtime on top of native code. In these tests, we measured the amount of time it took both NativeScript and Xamarin to create and populate large arrays.
Platform | Run 1 | Run 2 | Run 3 |
Native | 768ms | 774ms | 759ms |
NativeScript | 1135ms | 1129ms | 1138ms |
Xamarin | 3763ms | 3906ms | 3789ms |
You can see that NativeScript is roughly 3x faster than Xamarin when it comes to working with large data sets.
A little earlier in this article, I mentioned that the most important thing to users in terms of performance is frame rate, and that both NativeScript and Xamarin typically maintain good frame rates.
Even though it looks as if movement on TVs, computers and phones is smooth, these devices are actually drawing static images, known as frames, in very rapid succession.The human eye can only process so many frames per second. At some point, it can no longer see individual frames and will view movement as smooth. This happens at roughly 18 frames per second (fps). However, for every amount that the fps is increased after 18 fps, the motion and pictures become smoother and crisper. This tops out at 60 fps. When we're able to maintain a constant 60 fps rate, the UI appears buttery-smooth.
When native applications get complex, sometimes they will drop frames. This means that the frame rate fluctuates as the animation or processing gets intense. This causes the the UI to appear jerky. This commonly happens in long scrolling list of items.
To test this, we built an infinite scrolling list of items with images (pulled from Reddit), and then tested it on both NativeScript and Xamarin.Forms. You can see the frame rate results below as the list of items is scrolled. While NativeScript stays fairly close to 60 fps, Xamarin.Forms is all over the place. This results in a janky experience for the user.
This highlights another reason that we built NativeScript: developers need a framework that put a premium on speed. After working with hybrid frameworks for so long at Progress, we wanted to build something that was first and foremost blazingly fast. Everything else took a backseat to that goal in the creation of NativeScript.
One of the most important items to consider between Xamarin and NativeScript is the presence of so called Application Frameworks. These are frameworks developed for the purpose of organizing code, and making complex programming tasks (such as routing, dependency injection and state management) much easier by abstracting them away into a common code base. Good examples of application frameworks would be Caliburn.Micro for WPF and Angular or Ember for web development.
Xamarin ships an implementation of MVVM. This means that a developer can bind the UI to properties and methods on a model and when one changes, the other is changed as well. Here is an example of binding a simple text input to a `FirstName` property on a view model.
Class ViewModel : INotifyPropertyChanged {
String firstName;
public
event
PropertyChangedEventHandler PropertyChanged;
public
ViewModel() {
this
.FirstName = “Jane Doe”
}
}
<
Entry
text=”{Binding FirstName}”>
<
Entry.BindingContext
>
<
local:ViewModel
/>
</
Entry.BindingContext
>
</
Entry
>
MVVM in and of itself is not really an application framework as much as it is a pattern for binding. It does not address a lot of larger applications concerns like dependency injection, component composition, recommended code structure and the like. This is where so called application frameworks come in. For Xamarin, one such framework is MVVM Light
Xamarin apps can leverage the MVVM Light and MVVM Cross frameworks which provide the aforementioned pieces of necessary framework functionality. Both of these frameworks are open source and maintained by contributors from the community.
When using MVVM Cross or MVVM Light, the bindings remain largely the same as in the example above. These frameworks extend the out-of-the-box MVVM model to provide a complete application framework. MVVM Light is used more with Native Xamarin than Xamarin Forms as Forms provides much more of the necessary application framework pieces out of the box. Developers who have done extensive XAML development might be more familiar with MVVM Light since it is often used with other XAML based platforms.
Angular 2 is an application framework for TypeScript applications developed by Google. Angular is also open source and while they accept community contributions, the majority of the work is done by a dedicated team at Google.
While Angular is typically thought to only be applicable to the web, NativeScript supports Angular 2 as a first-class citizen and we recommend that developers use it when building NativeScript applications. Implementing this same form functionality from the example above in Angular 2 looks like this…
import {Component} from
'@angular/core'
;
@Component({
selector:
'my-app'
,
template:
'<TextField [(ngModel)]="firstName"></TextField>'
})
export class MyApp {
firstName: string =
"Jane Doe"
;
}
Notice that in Angular 2 there are no awkward interfaces or classes to inherit from. It's simply a component annotation and a standard class object. Angular's binding is almost magical and is one of the reasons why it's become so very popular with developers.
Angular also provides ways to build partial UI components share between pages (directives) as well as a model for dependency injection (injectables), along with an enormous developer community.
The other benefit to using Angular 2 is that it works on the web as well. This means that you can share a LOT of code between web and Angular apps. I recommend watching the ng-conf presentation from TJ VanToll and Jen Looper which demonstrates how to do this in 20 minutes. This is an evolution in multi-platform development, and it's powered by Angular 2 and NativeScript.
One of the most critical parts of development with any framework is the availability of plugins to extend that framework to make it do, well, whatever you might want. No place is this more important than on mobile.
For instance, neither iOS or Android provide a Side Drawer implementation out of the box. This means that neither do NativeScript or Xamarin. However, both of these frameworks have a plugin model which allows developers to build plugins like a side drawer which you can then download and use in your project.
NativeScript Plugins are delivered via npm packages. For instance, if I wanted to add a side drawer to the above simple form example, I could install Telerik UI For NativeScript, which includes a side drawer, advanced listview, charts, ect. That is done from the command line.
$ tns plugin add nativescript-telerik-ui
There are currently almost 500 NativeScript plugins available, and this number grows every month. This includes integrations for things like Firebase, Azure, Couchbase, TouchID, Audio, Video and more.
There are many plugins for both Xamarin and Xamarin Forms. Xamarin Forms plugins are distributed via NuGet when possible. There are currently Many plugins for Xamarin Forms are commercial, including Telerik UI for Xamarin. Commercial plugins are commonly installed by downloading a Dynamic Link Library (DLL) and adding it to a Xamarin project manually.
The exact amount of plugins available for Xamarin is difficult to measure since they are spread between open source plugins (37), plugins delivered on NuGet (2341), those listed on the Xamarin Plugins page (547) and some commercial plugins that aren't listed in any of those places.
I personally had a very hard time navigating the Xamarin Plugins landscape. I could not find a side drawer on Nuget for Xamarin.Forms. I found one on their official plugins site, but it was listed as iOS only. The good news is that I know that Telerik UI For Xamarin has a Side Drawer component that works for Xamarin.Forms and comes with a Windows Installer that makes it relatively easy to use the components with Visual Studio.
As developers, we often find it difficult to prescribe a given technology stack end to end to solve a specific problem - the answer often is ‘it depends'. This hesitation of choosing the right technology is compounded when the problem is as tricky as making native cross-platform mobile apps. Your chosen approach to go cross-platform should depend on the needs of your app, your skills, toolsets, maintainability of the app and eventually, the needs of your customer. To help with this decision, we have made this handy over-simplified flow chart.
You should go with NativeScript if:
You should go with Xamarin if:
No matter what your choice is, we are here to help. If you choose to go with Xamarin, check out our premium UI for Xamarin controls, which greatly simplify adding complex controls such as side drawers, complex editable listviews, charts and graphs to your Xamarin apps. If you choose to go with NativeScript head to nativescript.org and go through one of our getting started tutorials, which will get you up and running with NativeScript quickly. And in case you need polished components for NativeScript, make sure you check NativeScript UI.
In the end, having to make a choice between different technologies is a good thing. The more choices that developers have, the greater their chances of eventual success, which is really all that matters in the end.
Feel like we've missed something here or been unfair in our comparison? Please let us know in the comments! We want to foster an open discussion that surfaces the facts and your input is the best way to help us do that.