Python or JavaScript? While we’re still arguing over which has the upper hand or the brighter future, little doubt exists as to which owns the web’s front end. Until WebAssembly advances to the point where we can transparently compile other languages to use in the browser, it’s JavaScript in the browser or nothing.
Well, maybe not nothing. JavaScript is a favorite target language for “transpilers” that convert one programming language into another (see: TypeScript, Emscripten, Cheerp, Cor). And Python’s huge following and wealth of available libraries make it a great candidate to be converted, i.e. transpiled, into JavaScript.
Here are seven current projects for making Python useful in the JavaScript world. One stands out by being able to convert in both directions.
Brython
One of the promises WebAssembly makes is to allow us to use any language we choose to develop for the web, though this remains a distant goal. The philosophy behind Brython, at least as far as Python 3 is concerned, is why wait?
Brython implements a version of Python 3 for client-side web programming via a JavaScript library that emulates all of the keywords and most of the built-ins for Python 3. Scripts written in Python can be included directly in a web page. Brython supplies a high-level Python module interface (the browser
package) to interact with the DOM (Document Object Model) and the browser, handling all of the work normally done directly in JavaScript.
Plenty of live code examples and a gallery of mini-applications demonstrate how it all works. It’s even possible to use Brython to write a native Android app in Python. Async functionality is available, although you have to use Brython’s async
module instead of Python’s asyncio
.
Brython does not escape the restrictions imposed on JavaScript in the browser. For example, there is no support for dealing with the local file system. There is, however, support for using HTML5 local storage, if all you need is some way to persist data on a per-application basis.
JavaScripthon
JavaScripthon focuses strictly on translating Python 3.5 and later code to JavaScript, without trying to provide full in-browser support as per projects like Brython. It emits ES6 code to minimize the need for polyfills on the browser side, and plays well with tools like Webpack by preserving source maps.
Most of Python’s common keywords and behaviors are supported, including async
and await
, Python 3.6 f-strings, and Python class methods and inheritances. You can also insert JavaScript inline via a special function call, if you ever need to drop down to JavaScript directly.
Note that the last commits to the JavaScripthon project were in July 2022, though it has been updated to support Python 3.10 as its latest version.
Jiphy
The Jiphy name is an abbreviation of “JavaScript in, Python out.” In other words, Jiphy converts in both directions between the two languages. Plus, code from both languages can be intermixed before being converted to either target language.
Before you dive in and start converting all of OpenStack to JavaScript, take heed: Jiphy is not about full-blown codebase conversion. Rather, its function is, as the README puts it, “to reduce the context switching necessary for a Python developer to write JavaScript code and vice versa.”
The biggest drawback to Jiphy is that it supports only a subset of Python’s features. Neither classes nor default arguments are available, although decorators and exceptions are supported. Much of this is because Jiphy strives for a line-to-line relationship between the source and target code. To that end, there is no support for mapping Python’s standard library to JavaScript constructions.
Note that the Jiphy project hasn’t been updated since mid-2020. Jiphy should be considered strictly experimental until work on it resumes.
JS2Py
JS2Py converts JavaScript to Python, as the name implies, using a pure-Python conversion engine. It has official support only for ES5 right now, although there’s experimental ES6 support for the brave and bold.
JS2Py supports a great deal of cross-interoperation between Python and JavaScript. You can import existing Node.js modules in your Python code, by way of a js2py.require
method. Variables from the JavaScript side can be evaluated on the Python side, and Python objects can be used from JavaScript code as well.
JS2Py also includes a highly experimental virtual machine that evaluates JavaScript code from Python, but it’s not recommended for production use yet.
RapydScript
RapydScript “allows you to write your JavaScript app in a language much closer to Python without the overhead that other similar frameworks introduce.” The project is similar to CoffeeScript in that it ingests code written in an alternative language—in this case, a flavor of Python—and generates JavaScript that can run anywhere as-is.
Thus RapydScript provides the best of both worlds, bringing Python’s clean syntax to JavaScript capabilities like anonymous functions, DOM manipulation, and the ability to leverage JavaScript libraries like jQuery or Node.js. That’s right—you can use Rapydscript-generated code to drive web pages or Node apps.
Another convenient feature of RapydScrypt: It offers both Python and JavaScript nomenclatures for operations when possible. For instance, the $
special symbol used by jQuery works as-is in RapydScript, and arrays can support both the .push
(JavaScript) and .append
(Python) methods. However, the project has not been updated since May 2021, so it should be considered experimental.
PyScript
Like Brython, which uses some of the same underlying technology, PyScript allows Python to run directly in the browser. PyScript uses the Pyodide project, a Python runtime ported to WebAssembly, to make the browser a more hospitable environment for running Python as a web scripting language.
PyScript allows two-way communication between the JavaScript and Python environments. For instance, Python scripts can work with the Document Object Model, invoke JavaScript code, and work with results returned from it. But Python applications can also use the browser as an output device. For instance, the Python print()
command can be used to write output directly into a web page, in much the same way one would print output to the console.
PyScript also provides ways to work with packages available on the PyPI package index, although not all of them may behave as intended. For instance, PyScript doesn’t yet work with the requests
library or other Python tools for working with HTTP requests. However, PyScript does provide wrappers for JavaScript’s fetch
method to accomplish the same tasks.
Transcrypt
If you hear the name Transcrypt and think TypeScript, you’re not far off the mark. Transcrypt follows the same basic idea—it transpiles Python to JavaScript. It also tries to preserve, wherever possible, the structure and the idioms of the original Python code, including constructs like lambdas and multiple inheritance across classes.
What’s more, source maps can be generated for the transpiled code that point back to the original Python, so developers can debug using that code instead of the generated JavaScript. According to the documentation, Transcrypt accomplishes these tasks with CPython’s Abstract Syntax Tree module, which allows programmatic access to the way Python parses its own code.
One of Transcrypt’s biggest advantages is automatic access to the Document Object Model. If you try to access document.getElementById
in Python, for instance, the converted code will use the document.getElementById
in JavaScript. For programmers who want to use frameworks to do DOM manipulation, an online book provides step-by-step tutorials for using Transcrypt to write JavaScript applications using the React and Material-UI libraries.
An associated project, and one still heavily under wraps, is Numscrypt, which ports the NumPy math-and-stats library to JavaScript. So far Numscrypt provides only a subset of NumPy’s features, though these features (e.g., matrix math) are among the most commonly used. However, Numscrypt hasn’t been updated since 2021.