Back
Engineering

Why we Chose Node.js over Python for our Product

Why we Chose Node.js over Python for our Product cover image
Source Pexels

Launching a new product is a daunting road of experimentation that requires precision and calibration, like fixing a plane while flying. In our early MVP days (little shorter than a year ago), we started writing our web application with Vue for the Frontend and Python for the Backend. Six months later we launched our Alpha product for Swimm, and it was a more robust product that enables an experience for users switching between a CLI and the web app.

As a long time Pythonist, I followed my gut intuition and implemented the first version of our CLI in Python. It was unexpected but, several demos in with our first clients, revealed some major gaps we did not anticipate when starting off.

Lessons Learned: Node JS vs Python

It seems that Python and JavaScript are especially prevalent among young tech startups - according to Nick Kamyshan, CEO at Chanty, “The Most popular technologies I see startups use today are Python, Java, Ruby, C, Swift, JavaScript, and PHP.”

According to Stack Overflow’s developer survey in 2019, Python, the fastest-growing major programming language, rising in the ranks of languages and edging out Java in 2020, standing as the second most loved language (after Rust).

While it remains a heated debate [JS vs Python?], I didn’t really perform an in-depth comparison for choosing my go-to language for our CLI. Instead, I just used Python as it was the most intuitive solution for me. Yet as we started Demos with clients, we realized we needed to easily wrap the CLI as a tool that can be run, and distributed to clients.

With Python, this is not a trivial task. While it’s theoretically possible to send your Python code as it is, any difference between your environment and the client’s (e.g., different dependencies versions) may cause things to fail. After searching the web for solutions, we ended up using PyInstaller.

From the project’s website:

> PyInstaller freezes (packages) Python applications into stand-alone executables, under Windows, GNU/Linux, Mac OS X, FreeBSD, Solaris and AIX.

Pyinstaller

It sounded like a really good solution, but it turned out to be far from ideal. Our clients use different OS versions, in order to ship our code to Windows - I had to run Pyinstaller on Windows to ship to OSX - run Pyinstaller on OSX, and so on. While this can be solved with a CI/CD pipeline, things started to feel wrong:

  • For example, one client was using a specific distribution, Ubuntu16.04. I had used Pyinstaller to pack our CLI using Ubuntu 18.04, thinking it would comply with all linux distributions, but little did I know. Reading through the docs, this seems to be a known issue:

> Under GNU/Linux, PyInstaller does not bundle libc (the C standard library, usually glibc, the Gnu version) with the app. Instead, the app expects to link dynamically to the libc from the local OS where it runs. The interface between any app and libc is forward compatible to newer releases, but it is not backward compatible to older releases.

For this reason, if you bundle your app on the current version of GNU/Linux, it may fail to execute (typically with a runtime dynamic link error) if it is executed on an older version of GNU/Linux.

The solution is to always build your app on the oldest version of GNU/Linux you mean to support. It should continue to work with the libc found on newer versions.

  • The documentation includes other daunting notes, e.g. “For Python >= 3.5 targeting Windows < 10, the developer needs to take special care”.

All in all, I got to realize this solution isn’t good enough for us. While Python may be a wonderful language for the backend, it just seems like the wrong solution for a product that needs to run on a client’s machine, at least in case we don’t want to assume anything about the client’s environment without disclosing our code.

Eventually, I completely rewrote our CLI with NodeJS, throwing my Python implementation away. I ended up using the great project pkg for packaging our NodeJS code. We have now been running on Node.js for 6 months, and a team of 5 happy developers.

Happy Combo: Node.JS + Vue.JS

Another advantage of moving to Node JS was having (most of) our stack consist of one programming language - JavaScript.

It’s not uncommon to have multiple microservices, each written in a different language. When the entire codebase is in the same language, it’s easier to teach a team of developers specific topics on JavaScript taking out the hassle of teaching different languages and for different code areas.

This makes things much easier for engineer onboarding - at least when it comes to programming languages a new programmer onboarding the team needs to master. Of course they need to be aligned on our best practices for JavaScript and know JavaScript well, but at least most of these best practices will be the same across our repository.

In addition, when using pkg, private packages are stored as tokenized v8 compilations, so the source code isn’t available (especially not as easy as with PyInstaller’s compiled files).

Conclusions of Python-Enthusiast

Reading all of this, highlights some major goals we have as a team on our day-to-day: experiment, learn on the go, and make our collaboration processes more efficient. Our road map already includes a future shift to TypeScript, a subset of JavaScript with its own set of benefits also helpful for team collaboration.

On a personal note, I love Python. After years of programming in Python it wasn’t an easy choice for me to choose to develop a product in JavaScript. I miss the Context Managers that don’t exist in JS and the libraries I know so well. But also, as a linguist I might add, sometimes, transitioning between programming languages is like speaking a new language fluently but with a strong foreign accent (more about that in another post).

Paying forward some Python love: I recently created the Python Best Practice Public Playlist, for people who started learning xPython syntax, and are on a mission to learn and improve. To get it, shoot an email to info@swimm.io

...

Omer Rosenbaum, is Swimm’s Co-Founder and Chief Technology Officer. Cyber training expert and Founder of Checkpoint Security Academy. Author of Computer Networks (in Hebrew). Visit My YouTube Channel.