Miikka Oksanen Cross-platform UI Development: React vs Svelte

Metropolia University of Applied Sciences Bachelor of Engineering Information and Communication Technology Bachelor’s Thesis 20 May 2021

Abstract

Author: Miikka Oksanen Title: Cross-platform UI Development: React vs Svelte Number of Pages: 79 pages Date: 20 May 2021

Degree: Bachelor of Engineering Degree Programme: Information and Communication Technology Professional Major: Software Engineering Instructors: Simo Silander, Senior Lecturer Tommi Lundell, R& Squad Group Leader at Nokia Petteri Hiisilä, Senior Interaction Designer at Nokia

This thesis is part of a project done for Nokia. The goal was to gain insights about four UI frameworks - React, Svelte, React Native and Svelte Native - that will be used for determining which of the two native UI frameworks would be a better base for Nokia’s own native UI framework. Nokia’s native UI framework will be used to build customer applications for smartphones.

Each of the four frameworks was used to implement a front-end application GeoHub. The implementation processes were conducted with the purpose of gaining information about the development experience that the UI frameworks offer. Each GeoHub version (excluding GeoHub Svelte Native) was developed to the point that they could be considered completed.

The development experiences that the frameworks provided during the implementation of each GeoHub version were compared through five development experience attributes. React and React Native came out on top of their counterparts in this comparison. A major reason why Svelte and Svelte Native did not score as well as their counterparts was due to their immaturity. Thus, it was suggested that the progress of those technologies should be monitored.

It was also discovered that the amount of code that could be reused between web and the native implementations of GeoHub was low. The reason for this was deemed to be the extensive use of third party npm packages and the difference in display sizes between desktop and smartphone displays.

Keywords: cross-platform UI development, React, React Native, Svelte, Svelte Native

Tiivistelmä

Tekijä: Miikka Oksanen Otsikko: Järjestelmäriippumaton käyttöliittymäkehitys: React vs. Svelte Sivumäärä: 79 sivua Aika: 20.5.2021

Tutkinto: Insinööri (AMK) Tutkinto-ohjelma: Tieto- ja viestintätekniikka Ammatillinen pääaine: Ohjelmistotuotanto Ohjaajat: Lehtori Simo Silander R&D tiimin johtaja (Nokia) Tommi Lundell Vuorovaikutussuunnitelija (Nokia) Petteri Hiisilä

Tämä opinnäytetyö on osa Nokialle tehtyä projektia. Projektin tavoitteena oli kerätä tietoa neljästä käyttöliittymäsovelluskehyksestä (React, Svelte, React Native, Svelte ja Svelte Native). Tätä tietoa käytetään apuna päättämään, kumpaa kahdesta natiivista sovelluskehyksestä (React Native, Svelte Native) kannattaa käyttää perustana Nokian omassa natiivissa sovelluskehyksessä. Nokian natiivia sovelluskehystä tullaan käyttämään asiakkaille suunnattujen älypuhelinsovellusten kehittämisessä.

Kullakin sovelluskehyksellä toteutettiin GeoHub-käyttöliittymäsovellus. Näiden prosessien tavoitteena oli kerätä tietoa kunkin sovelluskehyksen tarjoamasta kehittämiskokemuksesta. Kolme neljästä GeoHub-sovelluksesta saatiin kehitetyiksi hyväksyttävään tilaan. ”Svelte Native”:lla kehitettyä sovellusta ei saatu valmiiksi.

Sovelluskehyksien tarjoamia kehittämiskokemuksia vertailtiin viidessä osa- alueessa. React ja React Native pärjäsivät vastaosiaan paremmin vertailussa. Suuri syy, miksi Svelte ja Svelte Native eivät pärjänneet vertailussa, perustui niiden uutuuteen. Täten ehdotettiin, että näiden teknologioiden kehitystä olisi seurattava.

Todettiin myös, että kierrätettävän koodin määrä verkko- ja natiivitoteutuksien välillä oli alhainen. Syyksi nähtiin laaja kolmannen osapuolen npm-pakkauksien käyttö sekä näyttökokojen eroavaisuus pöytäkone- ja älypuhelinnäytöissä.

Avainsanat: järjestelmäriippumattomien käyttöliittymien kehitys, React, React Native, Svelte, Svelte Native

Contents

List of Abbreviations

1 Introduction 1

2 Cross-platform UI Development 1

2.1 Definition 2 2.1.1 Cross-platform Software 2 2.1.2 UI and Its Development 3 2.2 Benefits of Using Cross-platform UI Frameworks 6 2.3 Problems Related to Cross-platform UI Development 7

3 React - Reigning King of UI Frameworks 11

3.1 History of React 11 3.2 Concepts 12 3.2.1 React Components 13 3.2.2 Virtual DOM 14 3.3 Syntax 16

4 React Native - Smartphone Servant of React 20

4.1 Origin Story 20 4.2 Adding “Native” to React 22 4.3 Syntax 23

5 Svelte - Odd Challenger 26

5.1 Performant Svelte 26 5.2 Not Your Traditional Web UI Framework 29 5.3 Reactive UIs with Svelte 30 5.4 Syntax 31 5.4.1 Reactive Statements with “$” Label 32 5.4.2 Value Bindings 33

6 Svelte Native - Work in Progress 34

6.1 Svelte Native and NativeScript 34 6.2 Syntax 36

7 Development Process 40

7.1 Development Environment and Version Control 40 7.2 Application Idea 41 7.3 Designing GeoHub 42 7.4 GeoHub 44 7.4.1 Use Cases 44 7.4.2 GeoHub UI in Screenshots 47 7.5 Implementation Processes 54 7.5.1 Evaluating Official Framework Documentation 55 7.5.2 Utilizing npm Packages 59 7.5.3 Framework Setup 60 7.5.4 Interactive Map with Leaflet 61 7.5.5 Reverse Engineering Nokia’s React components 62 7.5.6 Material Design UI Component Libraries 63 7.5.7 Working with React and Svelte 66 7.5.8 Working with React Native and Svelte Native 68

8 Conclusion and Future Plans 69

References 74

List of Abbreviations

UI: . A two-way interaction layer between humans and machines.

HTML: HyperText Markup Language. A text-based markup language for defining web page structures.

CSS: Cascading Style Sheets. A text-based style sheet language for altering the appearance of a structure defined in a markup language.

XML: Extensible Markup Language. A standardized, text-based markup language for writing human- and machine-readable documents.

API: Application programming interface. A collection of related interfaces that defines how one can interact with the software or hardware that owns it.

DOM: . A data representation of the structure and contents defined in a HTML or XML file.

APK: Android package. An installation file containing a single Android application.

AST: Abstract syntax tree. A data structure representing structure which is commonly used by for analysing semantic correctness of source code. npm: Node package manager. A collection of JavaScript software tools that automate the process of installing, removing and updating JavaScript software packages.

IDE: Integrated development environment. Software that provides tools for efficient software development.

1

1 Introduction

Nokia is looking to create a mobile-app development framework to support their existing web app framework. The framework will be used to create mobile applications that support the presentation of Nokia’s products to potential customers. Additionally, the framework should either work with Nokia’s existing framework which was built using React or be good enough to warrant the modification of their . This is because the mobile framework would also be used to make smartphone application versions of existing Nokia web applications.

The task was to evaluate two native UI frameworks, React Native and Svelte Native, as potential candidates to act as a base for Nokia’s smartphone UI development framework. Consequently, the web UI frameworks React and Svelte needed to be examined as well as the native UI frameworks are based on them. The focus was to be on the developer experience these technologies provide.

An ambitious plan was made to evaluate the frameworks. It consisted of building four similar applications, two web applications with React and Svelte and two smartphone applications with React Native and Svelte Native. During this process, the pros and cons of the technologies would be documented. Once completed, convincing arguments could be presented with documentation to back them up.

2 Cross-platform UI Development

Before introducing each of the UI frameworks, it is good to have an understanding on where and how they can be used. This chapter also introduces more precise definitions for some of the more ambiguous terms used in the thesis.

2

2.1 Definition

The term “cross-platform UI development” means the development of UIs that work on multiple platforms [1]. To properly define the term, it needs to be broken down into two parts: Cross-platform software and UI development.

2.1.1 Cross-platform Software

Cross-platform software, by definition, refers to a piece of software that has been implemented in a way where it will work on multiple computing platforms. A is simply an environment where software can be run. Operating systems, web browsers and hardware are all examples of computing platforms. A single computing device typically contains multiple layers of computing platforms. For example, a piece of hardware runs an operating system which in turn runs a web browser. [1.]

There are many ways to write cross-platform software. In the early days, developers implemented separate versions for each computing platform. This way of development was costly and slow as each version required developers that had knowledge of the inner workings of the underlying platform. Nowadays the process is much more efficient due to connecting interfaces that abstract the difference between computing platforms. [1.]

In this thesis, the platforms in the term cross-platform are narrowed down to smartphone operating systems and web browsers in general unless explicitly stated otherwise. This is due to the lack of a better suited term in the technological terminology. Consequently, the term cross-platform UI framework refers to a software that is used to build UIs for web browser applications and applications running on smartphone operating systems.

The UI frameworks that are discussed in this thesis are not cross-platform UI frameworks when considered individually. This, however, changes when they are coupled together. The first couple being React and React Native, and the second

3 being Svelte and Svelte Native. This coupling will start to make sense later when the similarities between the web application UI and smartphone application UI frameworks are discussed in detail.

The usage of the word “native” in the names of the UI frameworks discussed in here can be a little confusing. Native software is commonly defined to be software that runs on a specific operating system [2]. However, both React Native and Svelte Native are used to build UIs that can run on at least Android and iOS smartphone operating systems [3; 4]. Hence, the word native is used in the thesis to refer to smartphone operating systems in general.

2.1.2 UI and Its Development

A UI can be split into two interconnected representations. The first representation is known as the data representation which resides in hardware memory. This representation is called UI data tree here. It is typically a tree data structure consisting of UI element nodes. The implementation of a UI data tree typically varies between computing platforms. Concretely this means that the same methods cannot be used to work with for example, a web browser UI data tree and an Android UI data tree.

UI developers write code that acts as instructions determining what the UI data tree should look like at a given moment. The amount of detail UI developers need to put into the instructions depends on the used tools and target computing platform. As an example, conditionally adding a specific node to the web browser’s UI data tree requires three consecutive instructions, when communicating directly with the web browser: Create the new node, find the desired position of the new node on the UI data tree and finally add the node to the UI data tree (Listing 1).

4 if (someCondition) { // 1. Create new node const newNode = document.createElement(“div”) // 2. Find the desired position on the UI data tree const parentNode = document.querySelector(“#parent”) // 3. Add the new node to the UI data tree parentNode.append(newNode) }

Listing 1. Adding a new node to the web browser’s UI data tree without UI frameworks.

Declarative web UI frameworks such as React wrap the three instructions shown in Listing 1 into a single instruction as can be seen in Listing 2.

{someCondition ?
: “”}

Listing 2. Adding a new node to the web browser’s UI data tree by using React.

UI data tree is a new term that was invented for the thesis due to the lack of a fitting term in the technical terminology. It was invented for the purpose of discussing the way different computing platforms manage UIs in a general manner. The fundamental job of UI frameworks is to make issuing instructions to UI data tree implementations more convenient for UI developers. And since the UI frameworks discussed here target web browsers and smartphone operating systems, finding a general term for referring to the way those computing platforms manage UIs is essential.

The second UI representation is called the visual representation. This is what users see on their screens when they open an application. The visual representation gets built from the data representation in a process called rendering. Rendering is a computationally expensive process as it involves calculating UI element positions and painting them on screen [5].

User interactions on the UI do not directly affect the visual representation. A user interaction, otherwise known as a user event, gets translated into instructions that modify the UI data tree. It is only on the next render that the user gets to see the result of their actions on the screen.

5

Figure 1 describes the two UI representations. The UI data tree on the left side contains three nodes: one root node and two leaf nodes. The UI data tree that resides in hardware memory gets rendered into a visual representation consisting of pixels. The pixels are visible to the user of the UI through a monitor. In Figure 1 below, the leaf nodes are rendered inside and on top of the red root node. Although this is how UI data tree implementations are typically rendered by default, the computing platforms often offer ways for developers to alter this rendering schema [6].

Figure 1. UI data representation is rendered into a visual representation.

UI development is a process where UI developers design and implement a user interface, usually for an application. The process input is a list of features and design guidelines. The process output is a UI that contains the given features and follows the given design guidelines. [7.]

The process commonly starts with UI developers choosing a set of appropriate UI elements and styles. The developers then choose a layout for the visual elements so that the result looks visually pleasing and coherent. The layout should enable users to perform their desired actions with relative ease. [7] Once the UI design is set, the developers can start implementing the UI, often with the help of UI frameworks.

6

2.2 Benefits of Using Cross-platform UI Frameworks

Cross-platform UI frameworks allow entities to efficiently develop and maintain applications that reach an audience spanning across web browsers and smartphones. This is especially desirable for for-profit organizations that are constantly trying to attract customers in a cost-efficient way.

Having software products available on several platforms also brings companies security against changes in userbase behaviour. ’s signature social media application is a good example of this. The application launched solely on the in 2004 but over the years, the userbase of the application has shifted dramatically towards using the smartphone version as can be seen on Figure 2. [8].

Figure 2. Facebook’s userbase across different devices [9].

By using cross-platform UI frameworks, developers have an easier time implementing and maintaining UI code for multiple platforms. They can share

7 code between implementations targeting different platforms and thus need to spend less time making modifications to their codebases [1].

Another benefit is the reduced amount of knowledge needed to develop UIs for multiple platforms. Web application development traditionally requires the knowledge of HTML, CSS and JavaScript [10]. For traditional native application development, one needs to know the following languages: XML for both Android and iOS, or Kotlin for Android application development and Swift or Objective-C for iOS application development [11; 12]. JavaScript native UI frameworks such as React Native enable web developers to quickly start developing native applications without the need to learn native programming languages.

Cross-platform UI frameworks are beneficial for software companies in all maturity levels. New companies and start-ups use them to get their commercial applications “out there” as fast as possible to as many people as possible. As these companies grow their product catalogue, they do not need hire as many developers to maintain their products.

Potential savings have motivated top software companies to develop their own cross-platform UI frameworks. Both Google and Facebook have developed their own cross-platform JavaScript UI frameworks, and React together with React Native, which have later been open-sourced [13; 14].

2.3 Problems Related to Cross-platform UI Development

Most cross-platform UI frameworks have separate UI element lists for web browser and native platforms, meaning that developers need to specify at least two different UI structures when developing cross-platform UIs [1]. Although the UI element APIs that the platforms expose offer a similar selection of elements, the instantiation between related elements often differs.

8

Listings 3 and 4 contain instantiations for UI elements that are used for displaying images. Listing 3 instantiates an Android ”ImageView” UI element in XML with a width and height of 200 pixels. The image that is shown to the user is defined by the “android:src” attribute. Its value contains a path to an image file. The “android:contentDescription” attribute is used for attaching an alternative text description to the shown image.

Listing 3. An XML code snippet for instantiating an Android image UI element.

Listing 4 contains an instantiation for a similar image UI element that was instantiated in Listing 3 above. But the instantiation in Listing 4 is for an “img” web UI element that is written in HTML. Both instantiations have the same bounds, but the “width” and “height” attributes of the “img” UI element are automatically measured as pixels, so there is no need to add the “px” suffix.

Listing 4. A HTML code snippet for instantiating a web image UI element.

Listings 3 and 4 above have different source image paths (“src” attributes). The source image path of the web UI element leads to an image file that is accessed through the web. Smartphone applications do not have the luxury of having guaranteed internet access which is why using resources that are hosted in a web server should be avoided whenever possible. The source image path of the Android image element points to a file that is packed together with the application that uses the element. This way the image file is available regardless of whether internet is available or not.

9

Then there is the difference in screen sizes between desktop monitors and smartphone screens. The common desktop aspect ratio is 16:9 meaning that for every 16 pixels in the horizontal direction, there are nine vertical pixels. Smartphones held in a vertical orientation usually have the same aspect ratio but reversed (9:16). This means that in the design phase of UI development, UI developers usually come up with two UI layouts, one for each aspect ratio. [15.]

Listings 5 and 6 showcase a problem that the difference in aspect ratios can cause. They define seemingly equivalent UIs for Android (Listing 5) and web (Listing 6). Listing 5 contains some necessary XML boilerplate code, but the important part is the “TextView” UI element instantiation, or more specifically, the “android:layout_width” and “android:layout_height” properties. These properties are used to specify the bounds of the “TextView” UI element.

Listing 5. A simple Android UI definition in XML.

The web UI definition (Listing 6) is more concise and readable than the Android UI definition (Listing 5). The “p” UI element in Listing 6 has the same bounds as the “TextView” UI element in Listing 5.

Hello World!

Listing 6. A simple web UI definition in HTML.

Figures 3 and 4 display the corresponding visual UI representations for Listings 5 and 6. The Android UI code was run on an Android smartphone emulator with

10 a width of 1440 pixels and a height of 2560 pixels, giving it an aspect ratio of 9:16. The web UI code was run on a desktop display with an aspect ratio of 16:9. The text in the Android “TextView” UI element was not rendered into a single line (Figure 3) because it would have been longer than its width, which was set to be 200 pixels.

Figure 3. Cropped screenshot of the visual representation of the simple Android UI defined in Listing 5.

The visual representation of the web UI shown in Figure 4 has the “Hello world!” text in a single line. The text fits on a single line because of the aspect ratio of the desktop monitor.

Figure 4. Cropped screenshot of the visual representation of the simple web UI defined in Listing 6.

It is also worth noting that the text in the visual Android UI representation is tightly glued to the left side of the screen while the web UI text has a small left offset. This is because web browsers have an inherent CSS stylesheet known as the user agent stylesheet [16]. The user agent stylesheet contains a CSS rule that adds a margin of eight pixels to the “body” element.

11

Because of the problems stated above, the dream of having one codebase to “rule them all” when it comes to cross-platform UIs is often not a realistic one, even with the help of cross-platform UI frameworks. While abstracting away the differences between the APIs that different computing platforms offer for features such as button press handling is trivial, things become more complicated when trying combine entire UI data tree APIs under a single abstract API. This is one of the main reasons why both React and Svelte have separate native versions.

3 React - Reigning King of UI Frameworks

React was the second most popular web framework among all the programming languages according to the Stack Overflow’s 2020 developer survey [17]. Therefore, it is no surprise that one can easily find countless articles and blog posts describing what React is. But in order to fully appreciate the technology, it is essential to know how React came to be and what problems was it built to solve.

3.1 History of React

The cause that facilitated the birth of React came from Facebook’s advertisement division’s (Facebook Ad Org’s) trouble maintaining their ever-growing web applications. As is often the case with software projects, each update and feature that the developers added made their projects more complicated and thus made the development process slower. [18.]

There was one effect in particular that was causing the developers problems, called “cascading updates”. Facebook Ad Org’s web application UIs were built according to the traditional MVC (Model View Controller) pattern where each application UI would have a UI entity tree. A UI entity tree is essentially an extension to the UI data tree which allows tree nodes to contain their own logic and pass data between each other. [19.]

12

The UI entities were very tightly coupled, where entity controllers passed data up and down the tree. When the controller of an entity received new data, the model of the entity needed to decide whether to update the view of the entity. Because of the dependency relationship between the UI entity tree nodes, every other related entity needed to undergo the same process. This often cascaded across the whole tree, hence the name “cascading updates”. [19.]

The Facebook Ad Org developers had a hard time keeping track of all the UI entities which made it difficult to update application codebases reliably. Cascading updates meant that a modification in the code of a single UI entity could change the behaviour of UI entities that were several relations away. [19.]

The people at Facebook came up with a simple yet brilliant approach to UI entity trees that effectively solved the problems caused by cascading updates. Instead of modifying UI entities when they received new data, they would be instantiated again with the new data. This way developers did not need to know the previous data that the UI entity had, making the UI entities far simpler to understand. [19.]

With this approach, updates on a UI entity would only affect the UI entity and its children. As a UI entity was instantiated with new data, its children were also instantiated again. This was necessary, as updated data in a parent UI entity might be used in its children. As a result, updates on a UI entity deep in the tree would not cascade across the tree. [19.]

React was founded on top of this approach in 2011. It was open-sourced two years after its initial release and nowadays React is known to be a reliable and effective tool to build user interfaces. [18.]

3.2 Concepts

Although it is unclear whether the following concepts were first invented by the React team, it is clear is that React was the first web UI framework to utilize these concepts to a great effect.

13

3.2.1 React Components

React components are React’s take on UI entities, packaging structure, styling and logic in one function or class definition. They effectively replace the old MVC pattern where one would need to define a model, a view and a controller separately. In React, developers define component trees much like in the MVC pattern. But the relations between components are more clearly defined, which makes the code easier to maintain and update.

When one writes HTML code inside a React component definition, they are declaring React element instantiations. React elements are JavaScript objects that are used to describe a component instance and its properties. They are eventually transformed into DOM elements that are the building blocks of web UI data trees. [20.]

Each React component can have a state that controls when it should be updated. A component state is a JavaScript object which should not be mutated directly. Instead, one can change the state of a component by calling a specific function “setState” and providing a JavaScript object representing the new state as the argument to that function. Any “setState” call will be followed by React invoking its rendering library’s “render” method. As a result, the rendering library ReactDOM builds a new virtual UI data tree. [21.] The function name “render” is a bit misleading as it is not the same as building a visual representation of a UI from a UI data tree.

Figure 5 contains a diagram that shows how that visually demonstrates the information described in the previous paragraph. It shows how a state of a component gets mutated from its initial state through a “setState” call. The “setState” function definition includes a “render” function call.

14

Figure 5. Mutating a component’s state in React triggers a React rendering process [22].

Much like class constructors and functions, components can take input parameters known as “props” which is short for properties. Props are quite similar with component states, in that they are both JavaScript objects and updating them causes React to call its rendering library. The key difference is that a state is managed by the component that declared it while props are managed by the parent component that passed them. A component receiving props should consider them to be immutable. [21.]

3.2.2 Virtual DOM

When a web browser navigates to a valid web address, it makes an HTTP- request to a server. The server responds to the browser, returning a HTML document and any potential linked files like CSS and JavaScript files. The

15 browser then reads the HTML document into a UI data tree implementation known as the DOM. [5.]

Figure 6 shows how a web UI definition written in HTML looks like after it has been transformed to a DOM by a browser. The UI definition contains three container web UI element instantiations: “”, “” and “

”. The “div” element has two “

Listing 8. A web UI definition written with HTML, CSS and JavaScript.

The first “div” element with the “id” attribute value of “root” seems to have no purpose at first glance in Listing 8. But it was added so that both UIs (Listing 8, Listing 9) would be identical since it exists in every React UI by default. The React virtual DOM reconciliation worker performs DOM mutation operations relative to this “div” element. [20.]

Listing 9 contains a UI definition that is written with JSX and consists of React components. The two bottom-most React components “Counter” and “CustomButton” correspond to the text and the button in the UI. Those two components are used in the top-most component “App” which additionally contains the “div” HTML element with a red background. The “App” component also has a state with a property “counter” that starts from the value zero.

19 import { useState } from “react" const App = () => { const [counter, setCounter] = useState(0) const containerStyle = { backgroundColor: “red” } return (

setCounter(counter + 1)} />
) } const Counter = ({ counter }) => { return (

Counter has been clicked {counter} time(s)!

) } const CustomButton = ({ handleClick }) => { return ( ) } export default App

Listing 9. A web UI definition written with JSX that consists of React components.

The React component “App” in Listing 9 uses a hook called “useState”. Hooks were introduced in React version 16.8 with the purpose of allowing function components to use React component features like states. Components declared as functions can use the “useState” hook to declare and modify state properties. In this case the component has a state with a single property “counter” and calling the “setCounter” function is almost equivalent to changing the property with the “setState” function that class components use. There are some slight differences between using the “useState” setter function and “setState” but they are not discussed here. [29.]

A keen eye might notice that the way UI styling is written differs between the definitions in Listings 8 and 9. CSS syntax cannot be used directly inside React components but styles from external CSS files can be made available to components by importing them using the “import” statement. An alternative way is to define styles in a JavaScript object (“containerStyle variable in Listing 9). [30.]

20

4 React Native - Smartphone Servant of React

The year 2015 was a big year for the React team with the release of React Native and React version 0.14 [19]. Version 0.14 included a major change that separated the core React libraries from the rendering library ReactDOM which was tied to the DOM. The motivation behind this was to make the core React libraries integrable to other UI data tree implementations. Both releases made a clear statement: With React, developers can “learn once, write anywhere”. [28.]

4.1 Origin Story

Before React had been published, Facebook had extended their software product catalogue to smartphone app stores. The social media application Facebook Mobile launched on iOS in 2008 and on Android in 2010. The application versions were built separately which meant that Facebook had to have dedicated iOS and Android application developers who built their native applications. [31.]

With the emergence of React, Facebook started experimenting with using it to build smartphone applications [19]. Since the company had a lot of developers who were familiar with the framework, the potential benefits were huge: Facebook could effectively rotate React developers between web and mobile application projects leading to major savings in developer salaries.

The Facebook developers’ first attempt to port React to the native platforms was to use it with a native UI element that can display web content. The element is called WebView in Android and UIWebView in iOS. Running React inside an embedded browser that the element provided meant that the Facebook developers would not technically need to modify React as its runtime computing platform would still be a web browser. And they could still write code for utilizing native APIs that the operating systems provided, albeit those APIs could only be called outside of the embedded browser (Figure 7). [19.]

21

Figure 7. Top-level diagram of the initial attempt to port React to native platforms.

However, adding an embedded browser as an extra computing platform on top of the native platforms does not come without a cost. An obvious downside is that applications developed this way are inherently slower than purely native applications since browsers are not lightweight software.

A more serious problem for the Facebook developers was that they were restricted to web UI elements inside the embedded browser since native UI elements required direct access to Native APIs. Native UI elements provided far superior control for user events that are exclusive to handheld devices such as swiping and touching. The Facebook developers realized that React by itself was not the solution. They needed a UI framework that would produce UIs that would run directly on the native platforms. [32.]

The Facebook developers created abstraction layers on top of the native platforms so that they could utilize React components and virtual DOM in an

22 otherwise incompatible environment. The layers were connective in a sense that the interfaces they exposed would work with both Android and iOS. In doing so, they had managed to create a UI framework that could be used to write applications for both Android and iOS. This UI framework got the name React Native. [33.]

4.2 Adding “Native” to React

To run JavaScript code on Android, APKs built with React Native include a JavaScript engine known as JavaScriptCore. The engine is in-built to iOS because it is used by Safari, iOS’s default browser. At the time of writing, React Native is looking to replace JavaScriptCore with Hermes that offers better performance. [34; 35.]

At the beginning of runtime, React Native starts a dedicated JavaScript where React code will run. Communication between the JavaScript thread and native threads goes through an asynchronous React Native bridge. This prevents JavaScript code from blocking the main thread that is responsible for essential tasks like handling user gestures and rendering the UI on the screen. [34.]

Communication between the threads follows a custom message-based protocol which suits well into the use cases of React Native. For instance, React Native’s virtual DOM reconciliation worker uses the bridge to manipulate the native UI data tree implementation. It sends UI data tree modification operations as messages to native threads that have direct access to native UI data tree APIs and can thus execute the operations. The protocol states that the receiver can also send response messages which enables smooth two-way communication. [33.]

Figure 8 visualizes how React is integrated to the native platforms in React Native. React communicates with the native threads by sending and receiving messages through the React Native bridge.

23

Figure 8. Top-level diagram of the pieces involved in communication between JavaScript thread and a native thread.

The complex mechanisms described in this section were implemented with the goal of enabling developers to translate their React knowledge into knowledge that is useful in native application development. The next section will make it evident that all the hard work done by the React Native maintainers has not been for naught.

4.3 Syntax

Syntactically React and React Native are almost identical. A slight difference a React developer will notice when switching to writing React Native code is that React Native components return Core Components instead of React elements. Core Components are a layer of abstraction on top of React elements which allow developers to define general UI elements that are transformed into either Android UI elements or iOS UI elements. Common React elements have comparable Core Components as can be seen in Table 1. [36.]

24

Table 1. React Native UI elements and their kindred React UI elements.

React Native Core Component Comparable React element

Listing 13. A Svelte component definition containing reactive statements.

The variable “count” in Listing 13 belongs to the state of the Svelte component. It is declared and modified just like any other JavaScript variable. If the component definition in Listing 13 were written in React, it would need to have more verbose instructions such as “setState” for incrementing the value of the counter.

5.4.2 Value Bindings

Component-based UI frameworks typically enforce a top-down data flow to make UI behaviour more predictable. A parent component can pass data to a child component, and a component can set attributes on a UI element it encapsulates, but not the other way around.

Svelte allows developers to break the top-down data flow with the “bind” directive. Using the directive on a component property or a UI element attribute creates a two-way relationship where both the data sender and the data receiver can modify the data. [39.]

Listing 14 contains a simple Svelte component definition with an input UI element and a text element. The input element controls the component’s “name” variable. Changing the input element’s value causes the text in the UI element to change which will be shown to the user after the next rendering of the DOM.

34

Hello {name}!

Listing 14. A Svelte component with a bottom-up data flow.

UI logic that can be achieved by using reactive statements and value bindings is not something that can only be achieved with Svelte. But the amount of effort and code needed to replicate such logic with, for example, React is considerably higher. In other words, Svelte is syntactically more concise than React.

6 Svelte Native - Work in Progress

It is not surprising that Svelte’s unique approach to building reactive UIs sparked an interest on whether the approach could be applied to native platforms. The community-driven native UI framework Svelte Native is the realization of that interest, although it is not officially supported by Svelte [44]. Svelte Native is still a young project: Its first alpha version (0.1.1) was released as a npm package in 2019 and it has yet to have had its first actual release. At the time of writing, Svelte Native’s latest version in npm is 0.9.5. [45.]

6.1 Svelte Native and NativeScript

Being a community-driven project, Svelte Native lacks the development resources that corporate-backed projects like React have. So instead of building their own abstraction layers that are necessary for using web-based technologies on native platforms, developers working on Svelte Native took advantage of an existing solution: Svelte Native runs on top of another native framework, NativeScript. [46.]

NativeScript provides JavaScript APIs on top of native APIs which made it a good solution for Svelte Native since Svelte’s transpiler outputs JavaScript [43]. However, the API that NativeScript offers for mutating the native UI data tree implementations is quite different from the web browser’s DOM API. This posed

35 a challenge as the Svelte Native developers would need to create a layer between the transpiled JavaScript and NativeScript. The layer would accept DOM API calls and transform them into NativeScript API calls. [46.]

However, NativeScript’s high extensibility had attracted developers to create native versions for other web-based frameworks. The developers of NativeScript- Vue had already gone through the struggle of creating a DOM layer. Svelte Native developers used their work as a base for their Svelte Native DOM API, which saved a lot of work [46].

Figure 12 shows how a user interaction on a Svelte Native component is translated into a native UI data tree implementation mutation operation.

Figure 12. Flowchart of a Svelte component update in Svelte Native.

36

Even though NativeScript provided a way for Svelte Native maintainers to save lots of work, it might end up costing them in the future. Because Svelte Native is not officially supported by NativeScript, the NativeScript maintainers have no obligation to take Svelte Native into account when they release new versions. This adds an extra responsibility to Svelte Native maintainers who need to monitor whether some change in a new NativeScript version breaks something in their code.

6.2 Syntax

Svelte Native is syntactically identical with Svelte but as with React and React Native, the UI element collections of the frameworks differ. Svelte Native uses NativeScript’s UI elements that work in both iOS and Android. NativeScript UI elements follow the upper camel case naming convention where each word in the name of an element begins with a capitalized letter. However, in Svelte Native the first letter is not capitalized because the parser of the Svelte transpiler would otherwise confuse them with developer defined components that also follow the upper camel case naming convention.

In NativeScript, developers define UI layouts quite differently when compared to the other UI frameworks discussed here. The previous three UI frameworks mainly use CSS properties for positioning UI elements. NativeScript UI layout is commonly determined by layout container UI elements which control the layout of their children. The framework offers seven different layout container options. [47.]

Listing 15 showcases the use of NativeScript’s layout containers. It contains a simple component definition with Svelte Native. The component uses 3 different NativeScript layout containers. The top-most container “stackLayout” positions its children vertically starting from the top. The second container is “absoluteLayout” and its children’s default position is on the top left-hand corner. Specifying the “left” and “top” parameters adds an offset to the default position. The final layout

37 container is “dockLayout” and as its name suggests, its children can be docked to its sides with the “dock” parameter. [47.]

For the purpose of showing the differences between component definitions with Svelte Native and Svelte, Listing 15 is followed by another Listing 16 which contains a similar component definition with Svelte.

Listing 15. A Svelte Native component with three different layout containers.

The Svelte component definition requires drastically more code than the Svelte Native one. This is because NativeScript’s layout containers come with predefined layout rules while those rules need to be explicitly defined for web UI elements. The first two layout containers “stackLayout” and “absoluteLayout” in Listing 15 can be emulated quite effortlessly with HTML and CSS. The “dockLayout” layout container requires more complex code with several nested

38

“div” UI elements and CSS rules that are defined inside the “

Listing 16. A Svelte component that tries to emulate the Svelte Native component in Listing 15.

39

Figures 13 and 14 show the rendered results of the components defined in Listings 15 and 16. Figure 13 displays the rendered Svelte Native component.

Figure 13. Rendered result of the Svelte Native component definition in Listing 15.

The bounds of the Svelte component in Listing 16 were set to 500 pixels to better visualize the component (Figure 14). If the bounds were not set, the component would be rendered to take the whole width of the screen.

Figure 14. Rendered result of the Svelte component definition in Listing 16.

40

While the layout containers in Svelte Native are powerful, they are also very different from any web elements used in Svelte. This has the downside of reducing code recyclability when attempting to reuse Svelte code in Svelte Native UIs.

7 Development Process

Now that the four UI frameworks have been introduced, it is time to describe the process that led to the writing of the thesis.

7.1 Development Environment and Version Control

Most of the development was done on a virtual machine that was provided by Nokia. The virtual machine was only accessible from the company network, so a VPN was required when work was done remotely. The virtual machine was running the Fedora operating system which is a Linux distribution [48]. It had plenty of computing power and memory which proved to be essential when considering the requirements of the used software. TurboVNC was used to interact with the virtual machine. It is a virtual network computing software that enables the use of the target operating system’s graphical user interface [49].

Source code was written mostly with the Visual Studio Code editor. It had multiple relevant features that contributed towards a pleasant development experience. The Visual Studio Code Marketplace had a dedicated Svelte extension available. The extension had some bugs that will likely get fixed as the framework becomes more popular.

The web application development runtime environment was a Google Chrome web browser. Its developer tools were essential during the development process. The tools include a UI element explorer that was extensively used to inspect UI structure and styling during runtime. Familiarity with the software also played a big part on why it was used.

41

The runtime environment used for native application development was a smartphone emulator running the Android operating system. The software that was used to create the emulator is a part of Android Studio which is an IDE for developing Android applications [50]. The smartphone emulator required a lot of hardware resources and most of the time it worked sub-optimally.

Both React Native and Svelte Native provided an option for using a real smartphone device as the development runtime environment [44; 51]. This would have required that the smartphone and the machine that hosted the source code would have been connected to the same network. Due to security reasons, this option could not be used in this project.

Source code was hosted in an internal Nokia GitLab instance. Each of the UI frameworks that were evaluated had their own Git repository. Development was conducted in a way that a new Git branch was created for each application feature. When a feature was complete, its branch was merged into the master branch. Although the approach might have been excessive for a project involving a single developer, it was good practise for situations where such an approach is warranted.

7.2 Application Idea

As was briefly mentioned in the introduction, the UI frameworks were to be compared by implementing some application with all of them. The application did not need to have a use-case that was in line with other Nokia applications as the important part was to get information about the technologies used for developing the application.

After the decision that the frameworks would by compared by implementing some application with each of them, a meeting was held with thesis instructor Tommi Lundell about the features that the application should have. He suggested that the application should at least have an interactive map and allow users to upload and view media such as images and videos. These UI features were common in

42

Nokia’s customer applications, so it made sense to include them in this application as well.

Soon after the meeting, an application idea was presented to and accepted by Mr. Lundell. The application was to be for people that practise geocaching, and it received the name GeoHub. For those who are unfamiliar with the activity, one could describe geocaching as being modern day treasure hunting. It involves hiding and seeking containers, which are called geocaches, based on coordinate clues.

The purpose of the application was to enable its users to share their own geocaches and view geocaches others have posted on an interactive map. The users could add geocaches by choosing a location from the map that the application provided and give them a description and a difficulty rating. The application would also provide an option to attach some media hints to geocaches to make the geocache finders’ job easier.

7.3 Designing GeoHub

The design of the application was finessed with the help of thesis instructor Petteri Hiisilä. The first application implementation was developed based on a rough idea on what the application should look like. The design was then iteratively improved based on the feedback that Mr. Hiisilä provided.

The fonts and colours that were used in the design are standard Nokia resources. The used font family is called “Nokia Pure Font” and it was applied to the implementations from OpenType font files. The RGB values of the used colours were taken from a PDF file that contained information about all the colours that were in use in Nokia products. The custom blue colour of Nokia was the main colour of the application design. It is the left colour in Figure 15.

43

Figure 15. Cropped screenshot from a PDF file containing information about Nokia standard colours.

The UI elements of GeoHub were styled according to Nokia brand guidelines. The React components listed in the web UI framework of Nokia had these styles which is why the original plan was to implement the React version of GeoHub first by using those components and then try to emulate the design in the other versions.

Some parts of GeoHub UI layout were designed differently for web implementations and smartphone implementations. This is due to the difference in aspect ratios between desktop monitors and smartphone screens. Horizontally orientated layouts in the web implementation were flipped so that they became vertically orientated in the smartphone implementations.

44

7.4 GeoHub

The main outputs of the thesis are not the application implementations but the framework evaluations. Therefore, the completed implementations and the application use-cases are described here before the implementation processes.

7.4.1 Use Cases

GeoHub has two main use cases: Users can create geocaches (Figure 16) and users can view geocaches other users have posted (Figure 17). Because no server was implemented for GeoHub, the second use case only shows the geocaches that the user has created in their own application session. In other words, the created geocaches are not persistent. The use cases are presented in the next subsection through screenshots taken from the GeoHub implementations.

A new geocache is created through a geocache creation form which has three steps. The geocache creation process is described step-by-step in Figure 16. The next subsection contains figures that show what the application looks like on each step.

45

Figure 16. Creating a new geocache in GeoHub, step by step.

46

After creating a new geocache, it will appear as a blue circle marker on the map of the application. Clicking the marker opens a geocache inspection sheet where the geocache can be inspected. The steps in Figure 17 also include a step that navigates to a city specified by the user. This is done by typing the name of the city in the search bar of the application. Inputting a city name in the search bar causes the map to pan to that city’s location. The search bar can also be used when selecting a location for a new geocache.

Figure 17. Inspecting a created geocache in GeoHub, step-by-step.

While GeoHub is not an application that Nokia would ever offer to its customers, it does have features that could be tweaked to fit Nokia’s business model. For example, by replacing geocaches with 5G base stations, the application could be used for tracking 5G coverage across the world.

47

7.4.2 GeoHub UI in Screenshots

This subsection contains figures from the various steps that were introduced in Figures 16 and 17. The figures contain screenshots that were taken from the three application implementations that were finished. The Svelte Native implementation was not finished so there are no screenshots from it.

Figure 18 shows a screenshot taken from GeoHub React and it displays the UI that the user sees when he or she first opens the application. Clicking the light blue button on the bottom right-hand corner opens the geocache creation menu.

Figure 18. Screenshot taken from GeoHub React that shows the main view of the application (step 1. in Figure 16).

The geocache creation process begins by choosing a description and a difficulty rating for the geocache. The description field is a simple text field, and the difficulty rating is adjusted from the draggable slider below the text field (Figure 19). The user can close the from by pressing the “CANCEL” button or by pressing

48 anywhere outside the form. The screenshot in Figure 19 was taken from the Svelte implementation of GeoHub.

Figure 19. Screenshot of geocache creation form in GeoHub Svelte (step 2. in Figure 16).

The next step in the geocache creation process is to choose a location for the geocache. The location is chosen by pressing the “CHOOSE” button that is displayed in Figure 20. The screenshot in the figure was taken from the React Native implementation of GeoHub. In GeoHub React Native, the geocache creation form bounds match the bounds of the screen and it can be closed by tapping the white arrow on the top left-hand corner of the screen.

49

Figure 20. Screenshot taken from GeoHub React Native that shows the second step of the geocache creation form (step 3. in Figure 16).

Once the user clicks the “CHOOSE” button, the geocache creation form is temporarily hidden, and the interactive map is revealed. Also, a notification appears from the top of the screen that contains information on how to choose a location for a geocache (Figure 21). Pressing the map in this view will create a blue circle marker that is centered on the location that was pressed. In the web implementations of GeoHub, the area of the marker can be modified by dragging the marker. In the React Native implementation of GeoHub, the area is scaled by tapping the marker. The screenshot in Figure 21 was taken from GeoHub React.

50

Figure 21. Screenshot from GeoHub React location choosing view (step 4. in Figure 16).

Once the user has confirmed the location of the geocache, the geocache creation form is shown again. The form shows buttons for adding media resources that can act as hints for finding the geocache. Adding these resources is optional. The previously chosen location can also be modified by pressing the “CHANGE” button (Figure 22). In Figure 22, which contains a screenshot from GeoHub React Native, the user has added a local video file. The video can be played or changed after it has been added.

51

Figure 22. Screenshot from the second step of GeoHub React Native geocache creation form after a location has been chosen and a video has been added from the local file system. (step 7. in Figure 16).

The final step of the geocache creation process is to review the choices that were previously made (Figure 23). Pressing the “DONE” button creates the geocache and adds a blue circle marker to the map on the location of the geocache. The screenshot in Figure 23 was taken from the React Native implementation of GeoHub.

52

Figure 23. Screenshot from the last step of GeoHub React Native geocache creation form (step 8. in Figure 16).

If the user clicks a geocache marker on the interactive map, a geocache inspection sheet will open (Figure 24). The sheet will open from the right in the web implementations and from the bottom in the React Native implementation. The sheet displays the same information that the creator of the geocache added when the geocache was created. The sheet can be closed by pressing the “X” button on the top right-hand corner or by pressing on the map where there are no markers. If a new geocache is chosen by pressing its marker while the inspection sheet is still open, the sheet will update its contents to match the contents of the newly chosen geocache.

53

Figure 24. Screenshot of geocache inspection sheet being open in GeoHub Svelte (step 3. in Figure 17).

The geocache inspection sheet is scrollable in the case that the content of the geocache does not fit on the screen. In Figure 25, a video that was attached to the geocache under inspection can be brought to sight by scrolling down.

54

Figure 25. Screenshot of geocache inspection sheet being open in GeoHub React Native (step 3. in Figure 17).

Now that the GeoHub application has been presented through screenshots and use cases, it is time to move on to discuss the main points of the GeoHub implementation processes.

7.5 Implementation Processes

Approximately one month and two weeks were spent with the development of each GeoHub version. This includes the time spent learning about the technologies or more precisely, learning how to use them. For Svelte and Svelte Native, the learning process took longer than for their counterparts as they were

55 completely new technologies for the author who was also solely responsible for the implementations.

7.5.1 Evaluating Official Framework Documentation

This subsection is dedicated to evaluating the official documentation pages of the four UI frameworks. Official documentation refers to the documentation that can be found from the frameworks’ home pages and it includes any tutorials, quick start guides, concept explanations, API explanations, etc. that can be found from the home pages of the frameworks. Reading the official documentation or at least the quick start guide is often the first part of getting to know a new framework.

Having proper documentation is key for any framework. Even the greatest technologies are quickly forgotten, if only their creators know how to use them. It is the job of the documentation to provide a smooth introduction to a new technology. Most modern UI frameworks do this with interactive tutorials and quick start guides. For developers more experienced with the technology, the documentation should provide insights on how the framework works on a lower level. Good documentation is layered, so that developers new to a technology and developers that are familiar with it can efficiently find useful information.

Svelte provides an excellent interactive tutorial that goes through the core features of the framework, starting from the basics. Each feature in Svelte has a tutorial page which is split in half: The left side of the page is reserved for explaining the feature with text while the right side has an embedded live code editor where readers can modify the given Svelte code template and see the results of their actions in real time (Figure 26).

56

Figure 26. Cropped screenshot from a tutorial page in the interactive tutorial of Svelte [52].

The tutorial that React offers takes a different approach to introducing developers to the technology. It contains step-by-step instructions for building a simple application that uses the core features of React. The tutorial comes with a live code editor, but it must be opened in a new separate page. This together with the whole tutorial being in a single long page makes the React tutorial (Figure 27) harder to read than the tutorial that Svelte provides. Returning readers will also have a harder time finding a specific chapter because all the chapters in the tutorial are on the same page.

57

Figure 27. Cropped screenshot taken from the tutorial of React that shows the titles of the sections in the tutorial [53]. The size of the scroll bar on the top right corner tells that the page is very long.

The tutorial that Svelte Native provides takes a big nosedive when compared to the tutorial of Svelte. It follows the same single page format as the tutorial that React offers but it does not have a live code editor. Implementing a live code editor on a web browser for a native UI framework is less trivial than for a web UI framework. However, it did not stop the tutorial that React Native offers from

58 having one (Figure 28). This together with the lack of proper structure tutorial leaves its readers wondering whether the Svelte Native tutorial has been properly finished. [54.]

Figure 28. Cropped screenshot from React Native tutorial that shows a live code editor [55].

The documentation pages of the React pair are more extensive than those of the Svelte pair in the sense that they have pages for just about every one of their concepts. Although this could be chalked up to the difference in the complexities of the frameworks, it still does not explain why Svelte does not have a page dedicated for essential concepts such as its transpiler. One must look for

59 alternative information sources if they want to know more about the inner workings of the framework.

Finally, it is time to go through the part of the documentation that developers often use the most: the API description. Three out of the four frameworks have well written API descriptions. The Svelte Native API description is effectively a slimmed down version of the “UI & Styling” section in NativeScript documentation [47]. Considering that a large portion of the API that NativeScript offers can also be used in Svelte Native, this is not optimal.

7.5.2 Utilizing npm Packages

It was clear from the start of the implementation processes that npm third party JavaScript packages would need to be utilized whenever it was possible. Implementing all the application versions by only using the APIs that the frameworks offered would not have been possible with the given time for the project.

Being familiar with the npm package ecosystem around each of the frameworks proved to be valuable as it could be used as a metric when comparing the development experience the frameworks offer. For instance, if one of the frameworks did not have a compatible npm package for some nontrivial application feature, it would count as a con when evaluating the framework.

The downside of using npm packages was that it reduced code recyclability between the web and smartphone implementations. This is because very few npm packages are cross-platform. This means that if an npm package were utilized to implement some UI component in GeoHub React, the same package could not be used to implement the component in GeoHub React Native.

60

7.5.3 Framework Setup

The frameworks were initialized by using the npm command line interface and npx, which is a npm package for executing binary files that are in other npm packages. All that was needed to initialize React was to run a single command and the framework along with an application template were ready to be used (Listing 17). In addition to the application template, the setup script also created a test template and installed npm packages that could be used for automated testing of React applications. npx create-react-app my-app cd my-app npm start

Listing 17. Command line commands for initializing a React project in a folder called “my-app” and starting the project.

Setting up Svelte was not quite as effortless as setting up React because the required npm packages needed to be installed manually (Listing 18). However, the installed packages did not include packages for automated testing of Svelte applications. There were no plans to write tests for GeoHub, but for projects that need automated tests, not having a testing environment ready to go is not ideal. npx degit sveltejs/template my-app cd my-app npm install npm run dev

Listing 18. Command line commands for initializing a template Svelte project in a folder called “my-app” and starting the template project.

Setting up React Native and Svelte Native required more than just a couple of command line commands. Android Studio and Java Development Kit needed to be installed and an emulator needed to be created before the native UI frameworks could be used. Fortunately doing this part of the setup once was enough as both frameworks could use the same Android emulator. [44; 51.]

After successfully setting up an Android emulator, the UI frameworks could be installed and used. The React Native installation included a test template along

61 with packages that could be used for running automated tests. Running React Native required two terminals as two separate processes needed to be running at the same time (Listing 19). npx react-native init my-app cd my-app npm start

# Then on a different terminal: npm run android

Listing 19. Command line commands for installing and starting a fresh React Native application.

To run Svelte Native, NativeScript needed to be installed globally. This was done by adding a “-g” flag to the normal npm installation command. NativeScript installation provided the NativeScript command line interface which could be invoked with the “ns” command (Listing 20). The Svelte Native installation did not include packages for automated testing of Svelte Native applications. npm install -g npx degit halfnelson/svelte-native-template my-app cd my-app npm install ns run android

Listing 20. Command line commands for installing and starting a fresh Svelte Native application.

7.5.4 Interactive Map with Leaflet

GeoHub’s interactive map is powered by the JavaScript library Leaflet. It has an easy-to-use API and great documentation for quickly setting up interactive maps. It was chosen to be used in GeoHub over other JavaScript map libraries like MapBoxGL because it is free to use. MapBoxGL for instance, has a pricing model that starts off free but starts costing money once the application that uses it gets more users. While this was not going to be a problem for GeoHub, it is something that needs to be considered when making commercial Nokia applications. [56; 57.]

62

Leaflet works purely on web browser platforms [58]. It communicates directly with the web DOM which makes it hard to integrate into the virtual DOM of React. Fortunately, a npm package by the name of React Leaflet made it possible to use Leaflet with React components [59]. This package was used in GeoHub React with moderate success. Components that used React Leaflet behaved differently from regular React components which occasionally caused frustrating bugs where the map would not update properly. Using Leaflet in Svelte was simple since it could be used directly. After all, both Leaflet and Svelte communicate directly with the DOM.

Getting Leaflet to work in the native versions of GeoHub proved to be a time- consuming task. Neither framework had relevant npm packages for this feature and it quickly became clear why that was the case. Leaflet required a native UI element with an embedded web browser. Implementing the communication channel between the embedded web browser and the rest of the application was not a trivial matter.

Additionally, the communication between the embedded web browser and the rest of the app was not instantaneous. This meant that some of the map features that were in the web implementations of GeoHub could not be replicated in the native implementations. For example, when creating a new geocache in GeoHub React Native, the geocache location area is scaled by tapping instead of dragging (Figure 21).

7.5.5 Reverse Engineering Nokia’s React components

Although React GeoHub was originally planned to be implemented with UI components taken from the UI framework of Nokia, this proved to be impossible. The framework was undergoing a major update at the time and its latest available version was severely outdated. This rendered the Nokia’s framework unusable in GeoHub React which had a newer and incompatible React version.

63

Fortunately, the documentation pages of the framework contained demos of the components it offered. With the help of Google Chrome’s developer tools, the HTML and CSS code of the UI components could be read. This made it possible to reverse engineer components from the documentation pages.

The reverse engineering process was not a pleasant one. Because CSS-syntax could not be used directly inside React component definitions, it was not enough to simply copy and paste the CSS rules of the Nokia UI components from Chrome’s developer tools. The JavaScript code for the logic of the components was minified and obfuscated to reduce the amount of data that gets sent through the network. In short, the code was unreadable and thus the logic for the components that were reverse engineered was implemented by trial and error.

In the web implementations of GeoHub, the left side of the geocache creation form with the blue numbered circles (Figure 19) was implemented by reverse engineering parts from a Nokia form component. With Svelte, the process would have been much easier because Svelte component definitions can include pure CSS syntax.

7.5.6 Material Design UI Component Libraries

Each completed GeoHub implementation UI was mainly built from third party UI components. And most of those components were taken from UI component libraries that followed Google’s Material Design guidelines. The components were customized with Nokia colours and fonts to make them fit the design of GeoHub.

The implementations used different UI component libraries and their quality varied greatly. Material UI, which was used in React, was by far the most usable. Its documentation pages were excellent, and it offered an extensive number of components. Each component had a documentation page with multiple usage examples supported by a live code editor (Figure 29). But most importantly, the

64

Material UI components were highly customizable which made it easy to use them as bases for the components that were used in GeoHub React.

Figure 29. Cropped screenshot taken from Material UI ”Button” component’s documentation page [61]. Notice the number of sections on the right side of the figure.

The other used UI component libraries did not reach the quality of Material UI. The second-best UI component library was React Native Paper. It matched Material UI in terms of the quantity of components it offered but the documentation of the components was not close to the level of the documentation of the Material UI components. The documentation of the React Native Paper components consisted of a single usage example and a list of parameters, or properties as they are called in React and React Native, a component accepted (Figure 30).

65

Figure 30. Cropped screenshot taken from React Native Paper ”Button” component’s documentation page [61]. Full list of props could not fit into the screenshot.

Moving down the list of Material Design UI component libraries, there is Svelte Material UI. Despite its name, it was nowhere near Material UI in terms of quality. It provided an acceptable number of components, but they were extremely hard to use due to the quality of their documentation. Each component’s documentation consisted of a single demo without code (Figure 31). Worst of all, there were no component API specifications. The only way to know what parameters the components accepted was to read their source code in GitHub.

At the time of writing, three months had passed since the completion of GeoHub Svelte. Svelte Material UI documentation pages have improved from the last time

66 that they were used for developing GeoHub Svelte. The component documentations now have multiple demos with code attached to them. But they are still missing API descriptions.

Figure 31. Cropped screenshot taken from Svelte Material UI ”Button” component’s documentation page [62].

GeoHub’s Svelte Native implementation did not get to the point where choosing a Material Design would have been relevant. The reason for this is described in the next subsection.

7.5.7 Working with React and Svelte

Developing GeoHub React was overall a pleasurable experience. Most of the problems that rose during development had plenty of solutions available on the internet which ensured that the development process advanced smoothly. The abundance of React related material on the internet is no doubt a consequence of the popularity of the framework. On the other hand, finding solutions for Svelte related problems was not always easy. As Svelte becomes more mature and potentially gains a bigger user base, the amount of available material will most likely grow as well.

67

The difference in the popularity of the frameworks evidently played a part during the search for suitable npm packages. Finding packages for less common UI components such as a search bar with an autocomplete feature was not a problem for the React version. With GeoHub Svelte, the components often needed to be implemented from scratch because there simply were no packages that offered relevant components.

A long con that shadowed the GeoHub Svelte development experience was the lack of proper configuration instructions for its Rollup bundler. Simply put, Rollup is a JavaScript bundler that packs all the JavaScript files in a project into a single file. Bundlers are used to compress codebases to reduce the amount of data that needs to be transferred. Rollup has plugins that enable bundling of files belonging to other programming languages. The Svelte installation came with Rollup plugins for Svelte and CSS since Svelte supports writing CSS styles in their own files and then importing them to Svelte component definition files. [63.]

At one point of the GeoHub Svelte development process, one third party npm package containing a component that was needed for the GeoHub UI used styles defined in Sass language. This meant that a separate Rollup plugin needed to be installed and several hours were spent trying to get it to work. In the end, the npm package was discarded in favour of implementing the component from scratch. No problems of this sort were encountered during the development of GeoHub React.

The biggest strength of Svelte during the development process was the conciseness of its syntax. React components required more code on average due to the need for React component state handling. This also meant that the React components ended up being more complex than their Svelte equivalents. Ultimately GeoHub React code ended up being less readable than GeoHub Svelte code because of the sheer number of lines that needed to be parsed when reading the React component definitions.

68

7.5.8 Working with React Native and Svelte Native

Implementing native GeoHub versions proved to be far more difficult than implementing the web versions of GeoHub. This can be summed up by stating that the native UI frameworks offered worse tools for debugging during development than their web siblings. Essential features such as UI data tree state inspection were locked behind separate npm packages that needed to be manually installed.

The amount of learning material and solutions for the native UI framework problems was significantly lower. This was especially true during GeoHub Svelte Native development. When trying to solve Svelte Native related problems, it was more likely to encounter a solution to a somewhat similar NativeScript problem than it was to find a solution that applied to Svelte Native. With an extremely limited amount of information available about Svelte Native on the web, the development speed slowed down drastically.

Most of the GeoHub Svelte Native development time was spent trying to gather bits and pieces around the web into a coherent answer that would solve some encountered problem. This combined with the fact that the “live reload” feature did not work meant that GeoHub Svelte Native could not be finished in the time dedicated for the project.

Most of the modern JavaScript bundlers offer a “live reload” (otherwise known as “Hot Module Replacement”) feature that enables developers to make changes to applications and see the results of those changes without needing to restart the whole application. Bundlers manage to do this in a way that the changes are applied on the fly so that the state of the UI is preserved. The bundlers achieve this by monitoring the application files for changes. Once a change is detected, the bundler initiates a surgical process which ends with the bundler updating the bundled code that is running on a development machine. [64.]

69

The significance of the “live reload” feature in UI development should not be understated. The 10 seconds it took for GeoHub Svelte Native to restart after a change started quickly racking up to minutes and then hours of waiting. A task as simple as adjusting the font size of some text on the UI usually took at least two restarts because the first adjustment was often not quite right. The “live reload” feature worked flawlessly during the other GeoHub implementation processes.

The amount of code that could be recycled between the web and native implementations of GeoHub was surprisingly low. Only some very specific parts of UI component logic were usable on both web and native implementations of GeoHub. Another thing the native implementations could utilize was the overall UI structure of GeoHub since it stayed roughly the same when moving from one implementation to another.

8 Conclusion and Future Plans

Table 2 contains the condensed output of the work that the author has put into this project over the past six months. It rates the frameworks discussed here based on the development experience they offered during the development of their respective GeoHub versions. The given scores range from zero which is the worst score to five which is the best score.

The term development experience is broken down into six attributes to evaluate the frameworks more thoroughly: “Ease of installation” refers to the effort needed to install and configure a UI framework so that it was ready to be used. The second attribute “Usability” refers to the complexity of a UI framework from a developer’s perspective. This attribute includes concepts such as syntax structure and readability, but it does not touch on how a framework executes the developer’s instructions. As an example, evaluating the Usability of React included evaluating the complexity of React component definitions but did not contain the evaluation of the virtual DOM of React as a technology. This is because developers do not need to know about the inner workings of the virtual

70

DOM of React to use the framework, even though the component definitions they write directly affect it.

The third development experience attribute is “Documentation”. Its metrics were the quality and quantity of the available official documentation on the web. Official documentation refers to the documentation that was available on the home page of a framework. The fourth attribute is “Community”, and it describes the amount of support a framework had from the developer community around it. This attribute was measured by the quantity and quality of online resources around the framework. Examples of such online resources are third-party npm packages, blog posts and discussions about problems and solutions related to a framework.

The fifth and final attribute “Development environment” describes the reliability of the development tools that were associated with a framework. These tools included technologies such as bundlers and code editor extensions. Any unexpected behaviour from the development tools had a negative impact on this attribute’s score.

Table 2. Developer experience attribute scores for each of the UI frameworks discussed in this thesis.

Attribute name React Svelte React Native Svelte Native

Ease of installation 5 4 3 3

Usability 3 4 3 4

Documentation 4 5 4 2

Community 5 3 4 1

Dev. environment 5 3 3 0

Average 4.4 3.8 3.4 2.0

Both native UI frameworks got a worse “Ease of installation” score than their web counterparts. This is due to additional hassle that came from setting up the

71

Android emulator and the installation of additional required software as was described in Section 7.5.3.

The reason why there are only two distinct “Usability” attribute scores is because the way how UI components were defined did not really change from React to React Native and from Svelte to Svelte Native. The content of the definitions changed but their structure stayed the same. Svelte and Svelte Native got better “Usability” scores than their counterparts because of the clear structure Svelte and Svelte Native component definitions have. The reasoning behind the “Documentation” attribute scores was described in Section 7.5.1.

React got the best score in the “Community” attribute. The quantity of online resources related to each framework directly correlated with their popularity. The yearly framework npm package downloads can be compared to get a rough picture about the popularity distribution of the frameworks. In the year 2020, the react package had a little over 280 million downloads from npm while the svelte package had just short of three million downloads. This means that React was downloaded approximately 94 times more than Svelte. [65.]

The comparison between the native UI frameworks is even more lopsided. In the year 2020, the react-native package was downloaded a little over 14 million times from npm while the svelte-native package was downloaded approximately seven thousand times. That means that React Native was downloaded approximately two thousand times more than Svelte Native. [65.]

The “Development environment” score of Svelte Native is the only zero in Table 2. The problems with the “live reload” feature decreased the score drastically. The hours that were spent waiting for GeoHub Svelte Native to reload and the days that were spent trying to fix it to no avail amounted to at least 20 percent of the time that was spent working with the framework. React Native got a score of three in this attribute and the reason why it did not get a full score was its inability to reproduce the development environment that React provided.

72

As the average attribute scores in Table 2 state, the author recommends the use of React Native over Svelte Native to act as a base for Nokia’s native UI framework. Consequently, the current web UI framework of Nokia that is based on React should not be rewritten with Svelte. Even though Svelte shows promise, it has not yet reached the point in maturity that it should be seriously considered for commercial use. This is even more the case with Svelte Native. Time will tell whether these technologies reach the level of React and React Native. Because of their potential, the author recommends that a close eye should be kept on them in the future.

If this project or a similar project were to be conducted again, there are a couple of things that could be done differently. At the cost of more work, the frameworks could be tested by using the bare minimum amount of third-party code, namely npm packages. This would better test the usability of React or Svelte code in React Native or Svelte Native. Additionally, the people responsible for carrying out the project could first become familiar with the studied technologies by for example, having one project’s worth of experience with each of them. With the limited time that was allocated for the implementation of the project and writing of the thesis, having to spend time learning Svelte and Svelte Native left less time for using them for development.

Experimenting with the tools the frameworks offered for setting up automated tests would have added more value to the study. Having comprehensive automated tests for an application brings safety against unexpected bugs and reduces manual testing labour over time. Also testing whether the native versions of GeoHub worked on an iOS device would have been worth doing if a Mac device had been available. The native versions of GeoHub were developed solely for Android due to Apple’s policy, which prevents developers from building native code for iOS without a Mac device [66].

Finally, it is worth considering whether adding a server would bring additional value to the evaluation of the frameworks. GeoHub was implemented as a front- end application which meant that the implementations did not communicate with

73 a server. The reason why it was left out of this project was because communicating with a server is not something that UI frameworks are typically responsible for. Furthermore, having to implement a server would have taken time away from the front-end development.

74

References

1 Bishop, Judith; Horspool, Nigel. 2006. Cross-Platform Development: Software that Lasts. Web resource. IEEE. . 9.10.2006. Accessed 3.4.2021.

2 Fitzpatrick, Jason. 2013. What Does it Mean for Software to Run Natively. Web resource. How-To Geek. . 25.6.2013. Accessed 4.4.2021.

3 React Native – Learn once, write anywhere. 2021. Web resource. . Accessed 4.4.2021.

4 Svelte Native – The Svelte Mobile Development Experience. 2021. Web resource. . Accessed 4.4.2021.

5 Hiwarale, Uday. 2019. How the browser renders a web page? – DOM, CSSOM and Rendering. Web resource. Medium. . 3.8.2019. Accessed 5.4.2021.

6 position – CSS: Cascading Style Sheets. 2021. Web resource. MDN Web Docs. . 27.4.2021. Accessed 5.4.2021.

7 Silva, Patrícia. 2020. UI Developer: A Mix of Design and Front-end. Web resource. Imaginary Cloud. . 27.8.2020. Accessed 5.4.2021.

8 Hall, Mark. 2021. Facebook. Web resource. Encyclopedia Britannica. . 16.2.2021. Accessed 6.4.2021.

9 Tankovska. H. 2021. Device usage of Facebook users worldwide as of January 2021. Web resource (image). Statista. . 9.2.2021. Accessed 6.4.2021.

10 Cox, Lindsay. 2020. Web Design 101: How HTML, CSS, and JavaScript Work. Web resource. HubSpot. . 19.10.2020. Accessed 6.4.2021.

11 Application Fundamentals. 2021. Web resource. Android Developers. . 23.2.2021. Accessed 8.4.2021.

75

12 Karczewski, Dawid. 2020. Swift vs Objective-C: Which Should You Pick For Your Next iOS . Web resource. Ideamotive.

13 Angular. 2021. Web resource. . Accessed 8.4.2021.

14 React – A JavaScript library for building user interfaces. 2021. Web resource. . Accessed 8.4.2021.

15 Rusen, Ciprian. 2019. What do the 720p, 1080p, 1440p, 2K, 4K resolutions mean? What are the aspect ratio & orientation. Web resource. Digital Citizen. . 7.3.2019. Accessed 9.4.2021.

16 Kenneth Stoddard. 2016. What is a user agent stylesheet. Web resource. Stack Overflow. . 20.2.2016. Accessed 9.4.2021.

17 Stack Overflow Developer Survey 2020. 2020. Web resource. Stack Overflow. . Accessed 9.4.2021.

18 Hámori, Ferenc. 2018. The History of React.js on a Timeline. Web resource. RisingStack. . 4.4.2018. Accessed 11.4.2021.

19 Occhino, Tom. 2015. React.js Conf 2015 Keynote – Introducing React Native. Web resource (video). YouTube. . 29.1.2015. Accessed 11.4.2021.

20 Rendering Elements. 2021. Web resource. . Accessed 12.4.2021.

21 Cherecheș, Ovidiu; Farwell, Corey; Manning, James; Schiefer, Roman. 2017. props vs state. Web resource. Github. . 6.7.2017. Accessed 12.4.2021.

22 What is component state. 2020. Web resource (image). Packt. . Accessed 12.4.2021.

23 Virtual DOM. 2018. Web resource (image). . Accessed 13.4.2021.

24 Accessing the DOM. 2021. Web resource. MDN Web Docs.

76

US/docs/Web/API/Document_Object_Model/Introduction#how_do_i_acce ss_the_dom.3f>. 9.4.2021. Accessed 13.4.2021.

25 Ravichandran, Adhithi. 2018. React Virtual DOM Explained in Simple English. Web resource. . 3.12.2018. Accessed 13.4.2021.

26 Introducing JSX. 2021. Web resource. . Accessed 15.4.2021.

27 XHP: Introduction. Date of publication unknown. Web resource. . Accessed 16.4.2021.

28 Alpert, Sophie. 2015. React v0.14. Web resource. . 7.10.2015. Accessed 16.4.2021.

29 Introducing Hooks. 2021. Web resource. . Accessed 14.4.2021.

30 DOM elements. 2021. Web resource. . Accessed 16.4.2021.

31 Arthur, Charles. 2014. Facebook’s mobile journey has only just begun, but already makes money. Web resource. Guardian. . 3.2.2014. Accessed 17.4.2021.

32 Occhino, Tom. 2015. React Native: Bringing modern web techniques to mobile. Web resource. Facebook Engineering. . 26.3.2015. Accessed 17.4.2021.

33 Sjölander, Emil. 2018. React Native, The Native Bits. Web resource (video). YouTube. . 14.9.2018. Accessed 17.4.2021.

34 Zagallo, Tadeu. 2016. Optimising React Native: Tools and Tips. Web resource (video). YouTube. . 26.2.2016. Accessed 18.4.2021.

35 Using Hermes. 2021. Web resource. . Accessed 18.4.2021.

36 Core Component and Native Components. 2021. Web resource. . Accessed 18.4.2021.

77

37 Harris, Rich. 2016. Frameworks without the framework: why didn’t we think of this sooner. Web resource. . 26.11.2016. Accessed 19.4.2021.

38 Results for js web frameworks benchmark. Date of publication unknown. Web resource. . Accessed 19.4.2021.

39 Harris, Rich. Rethinking reactivity. 2019. Web resource (video). YouTube. . 22.4.2019. Accessed 19.4.2021.

40 What is compiler. 2016. Web resource. WhatIs. . Accessed 19.4.2021.

41 Michel, Benjamin. 2015. What is a transpiler. Web resource. BAM. . 29.4.2015. Accessed 19.4.2021.

42 Couriol, Bruno. 2019. Svelte 3 Front-End Framework Moves Reactivity into the JavaScript Language, Q&A with Rich Harris. Web resource. InfoQ. . 6.5.2019. Accessed 20.4.2021.

43 Harris, Rich. 2017. Architecture behind Svelte. Web resource. GitHub. . 13.12.2017. Accessed 20.4.2021.

44 API Docs – Svelte Native. Date of publication unknown. Web resource. . Accessed 21.4.2021.

45 svelte-native – npm. 2019. Web resource. npm. . Accessed 21.4.2021.

46 Lauer, Rob. 2019. A Interview with Svelte Native Creator David Pershouse. Web resource. . 10.10.2019. Accessed 21.4.2021.

47 NativeScript Docs – UI & Styling. Date of publication unknown. Web resource. . Accessed 22.4.2021.

48 Getting started with Fedora. 2021. Web resource. Fedora Docs. . Accessed 23.4.2021.

49 A Brief Introduction to TurboVNC. 2021. Web resource. . 24.2.2021. Accessed 23.4.2021.

78

50 Meet Android Studio. 2021. Web resource. Android Developers. . 5.4.2021. Accessed 23.4.2021.

51 Setting up the development environment – React Native. 2021. Web resource. . 12.3.2021. Accessed 23.4.2021.

52 Svelte Tutorial – Adding data. 2019. Web resource. . Accessed 25.4.2021.

53 Tutorial: Intro to React. 2021. Web resource. . Accessed 25.4.2021.

54 Tutorial – Svelte Native. 2019. Web resource. . Accessed 25.4.2021.

55 Introduction – React Native. 2021. Web resource. . Accessed 25.4.2021.

56 Leaflet – a JavaScript library for interactive maps. 2021. Web resource. . Accessed 26.4.2021.

57 Mapbox pricing. 2021. Web resource. . Accessed 26.4.2021.

58 Ortega, Iván. 2020. Leaflet – NativeScript support for Android & IOS. Web resource. GitHub. . 23.7.2020. Accessed 26.4.2021.

59 Introduction – React Leaflet. 2021. Web resource. . Accessed 26.4.2021.

60 React Button component – Material UI. 2020. Web resource (image). . 28.9.2020. Accessed 27.4.2021.

61 Button – React Native Paper. Date of publication unknown. Web resource (image). . Accessed 27.4.2021.

62 Perrin, Hunter. 2021. Button – SMUI. Web resource. . 15.4.2021. Accessed 27.4.2021.

63 Guide - rollup.js. Date of publication unknown. Web resource. . Accessed 28.4.2021.

79

64 Hot Module Replacement – . 2021. Web resource. . 5.2.2021. Accessed 28.4.2021.

65 Npm-stat: download statistics for NPM packages. 2018. Web resource. . Accessed 28.4.2021.

66 Can I use Windows 10 to develop IOS apps? 2017. Web resource. Apple Developer Forums. . Accessed 29.4.2021.