Skip to main content

Kivy vs React-Native for building cross platform mobile apps

I've built three apps now using Kivy and one with React-Native, just wanted to share my thoughts on both.

Just a warning, I am strongly biased towards python and this is all based on opinion and experience and is thus worth what you pay for it. I don't claim to be an expert in either of these, just have worked with each for several months.  If something is incorrect I'd love to hear advice.

Kivy


Demo of one of the apps



Pros:


  1. Nice to be able to run natively on the desktop WITHOUT a simulator
  2. Python is easy to work with
  3. Use (almost) any python library
  4. Very easy to create custom widgets
  5. Kivy properties and data binding just work. Way nicer than React's "state" / flux / redux whatever you want to call it (stupid?). 
  6. Native interfaces (pyjnius) and (pyobjc)
  7. Runs and feels pretty smooth

Cons:

  1. Default widget toolkit looks like Android 4.4. Requiring you use your own widgets or a theming kit like KivyMD if styling bothers you
  2. Creating dynamic widgets declaratively is not yet supported (loops for instance)
  3. Startup times are SLOW. A simple hello world app on a Nexus 5 takes about 2 seconds to start.  The thermostat app above (including KivyMD, several screens, and twisted) takes 10-15 seconds startup on a Nexus 5.
  4. Bundled app sizes are huge and extracted space usage is even bigger. My simple thermostat app is 30 mb packed and almost 90MB extracted 
  5. Building sucks.
    1. I literally had to spend hours chasing down the cause of build errors. 
    2. Adding new modules that require compilation is a pain. You have to create "recipes" for any library with compiled components . And have to figure out how to cross compile them.
    3. Android / iOS projects are created with templates. If you have to do anything NOT supported by default it's very hackish (for example adding an XML resource). You have to wade through several copies of template / build versions of the project to find where the correct place is to update the files you need. None of this is documented. React's implementation is much cleaner.
  6. Debugging on the platform is more old school, open app, test, crash, view log as opposed to reacts popup (at least for JS only crashes). Although on Kivy debugging on the desktop is much easier.
  7. Kivy maps is much more laggy / slow than React's
  8. KvLang is a string, no syntax highlighting or anything.

In my experience using Kivy is fine for any app that will be opened once and run for a long time such as games and single app control interfaces but not so much for day to day app on someones phone.  It works well with model driven applications that have complex dependencies and interactions.

React Native

Pros:

  1. App startup is almost immediate
  2. Bundled app size is reasonable ~8 mb
  3. Easy to build and add / remove packages
  4. Adding native modules is straight forward and intuitive
  5. Declarative widget definitions that supports conditional expressions and looping of widgets
  6. ES6 features make JS not as terrible (opinion)
  7. Async builtin is nice (ie using fetch().then()) to avoid blocking/threads
  8. Debugging JS crashes is easy with the stack trace popups
  9. Hot / Live reloading saves a lot of time, especially for styling changes
  10. Minimal changes needed to use the same code for Android / iOS

Cons:

  1. The state "flow", flux, (insert cool name here) etc.. , whatever you call it is a pretty terrible implementation in my opinion. Why re render and diff the whole view to a virtual dom when you only have to change one text field? 
  2. There's "quasi" states between rendering due to the fact that setState is done asynchronously. This causes tons of headaches when you're trying to render things conditionally such as when an error occurs. I've seen several cases where the view is not synced properly with the state. 
  3. There are no models, only components with state. 
  4. No way to bind to property changes (that i know of) so any state dependencies must be manually linked somehow. 
  5. If you want to use a global state, you must force updates when making changes in a different component. It should just update automatically.
  6. Remote debugger in browser is not as nice as a builtin debugger in the IDE
What React get's right is the build process and ease of adding and removing libraries. This saves tons of time and allows you to quickly build apps. Also the declarative JSX inline is also very nice as opposed to kvlang which is just a giant string.  

However, I think React Native fails with it's lack of  a data model and no observable state changes. They break the MVC pattern and just force you to use setState which rerenders all the time. It can become a big headache chasing down why your variables are correct but the view is jacked up.

It seems as if their "flux" design was used to force unknowledgeable programmers how to properly update a model and subsequent view. Javascript lacks the type/protection restrictions to do this in the language and is thus abused.

Overall i'm impressed with React Native and think it's a good way to develop cross platform apps for really anything.  

Summary 

In all I would say which you use depends on your use case. 

For single app interfaces I think Kivy is great and much preferred due to it's better properties model.  Overall I would give Kivy (currently at 1.9.2beta) a 6.5 out of 10. If Kivy could make building less hackish, ditch the template based project generation and just use a method more similar to react, I think it would go up to 8 of 10.  If it could load almost immediately and use native widgets id give it a 9 and use it for everything.

I'd give React Native (currently 0.44) an 8.5 out of 10.  Building is easy, the apps are fast enough, and the JSX approach is intuitive. Lots of support and a large community. The app feels native in both startup and interaction. Only a few annoyances due to their "flux" design that cause issues. 

It is good to see Python finally starting to make it's way into the mobile space and kudos to all the hard work put in by the Kivy team. It's really unfair to be comparing a product from the small team backing Kivy to a billion dollar corporation like Facebook with unlimited resources. I hope to see more work done in the Python arena.

I'd be interested to see a python implementation similar to React's native bridge model that used native widgets instead of doing everything in OpenGL. Update check out enaml-native




Comments

  1. This is really a nice and informative, containing all information and also has a great impact on the app design.
    infinite logo design
    logo design uk
    professional app development

    ReplyDelete
  2. I read that Post and got it fine and informative. Please share more like that...
    erp in chennai

    ReplyDelete

Post a Comment

Popular posts from this blog

Control Systems in Python - Part 1 - Bode and Step Response

I hate matlab with passion, yet sadly, nearly everyone uses it.  I'm a fan of Python and open source stuff so here's a simple article on how to do some common control systems stuff in Python.

First we need to make sure the environment is setup.
Install IPython (or you can use any other python shell, but a unicode supported shell is preferred)Install python-control (numpy, scipy)Install sympy
These should do if your on Ubuntu/debian:

sudo apt-get install python-sympy python-numpy python-scipy python-matplotlib ipython
Then you need to install python control, see How to download and install python-control
Intro to using SympyOpen ipython and run the following:

import sympy from sympy import * sympy.init_printing() s = Symbol('s')

Now we can do things like define transfer functions using the symbolic variable s.


We can expand the bottom using the .simplify() method

and we can do something more complex like...
which is really nice because it does all the multiplication for us... and it’…