Pure Python Web Application Development – NO CSS, HTML, or Javascript needed or wanted!

Practical Introduction

This guide is designed to help you find a pure Python web application development solution fast. If you want theory, see the “Theoretical Introduction” section below. Otherwise just jump right to the practical guide and choose what works for you.

Theoretical Introduction

Welcome to 100% pure python web development. Sayonara to the HTML/JS/CSS soup. The driving concept behind 100% pure Python web development was captured long before the WWW existed in Chapter 4 of the classic software engineering text “Structure and Interpretation of Computer Programs”:

It is no exaggeration to regard this as the most fundamental idea in programming:
The evaluator, which determines the meaning of expressions in a programming language, is just another program.
To appreciate this point is to change our images of ourselves as programmers. We come to see ourselves as designers of languages, rather than only users of languages designed by others.

Abelson and sussman ““Structure and Interpretation of Computer Programs”

By developing web apps entirely in Python, Python serves as a metalanguage generating the target languages of CSS/HTML/JS!

If you think about it, we already use tools like lxml to generate XML. We already use dictionaries to abstract away JSON. The benefits of Python for XML and JSON are undisputed and widely accepted. So similarly, we are seeking to use Python as a metalanguage for HTML/JS/CSS. 

This greatly simplifies and abstracts web application development. Prior to the web, graphical applications were largely developed in just a single language. Text applications are still this way. Web application has gone through some phases, that I have discussed elsewhere:

  1. server side includes
  2. CGI scripts
  3. Java applets
  4. client-server partial page reloaded apps developed with a back-end and front-end

Even though stage 4 is where we are, stage 3 was a more unified approach to GUI development, very similar to the way X-windows and C/TCL/Smalltalk were used to develop GUI apps prior to the web.

The problem we have exists because…

The web was never really meant for applications: 

The WWW was designed to make information browsable for anyone. Applications were something you downloaded and installed on your personal machine. But before we knew it, people were adding more and more functionality to websites by sticking in a little JQuery here or some PHP there. And before we knew it, the line between website and web application became blurry.

While data storage technologies have changed fairly slowly, the best way to develop in Javascript and even CSS changes quite a bit as you can see.

The need for robust software development was left behind in a frenzy of creating a soup of technologies. But some people saw the pitfall and started working on alternative solutions that allowed a software developer to develop in one language yet generate the plethora of languages needed for a web application. In Java, we saw zk and Vaadin. In Scala, we saw mind-blowing live coding in ScalaJS and in Smalltalk we saw Seaside.

But most impressively we saw UrWeb – a metalanguage inspired by ML that generated typesafe back-end and front-end code, thereby preventing all the things that adhoc-tossed-salad modern web development suffers from:

  • code-injection attacks
  • invalid HTML
  • Dead intra-application links
  • mismatches between HTML forms, and the fields expected by their handlers
  • client-side code that makes incorrect assumptions about the AJAX-style services that the remote web server provides
  • invalid SQL queries
  • improper marshaling or unmarshalling in communication with SQL databases or between browsers and web servers

We thus see why Pure Python Web Development is a necessity:

  • security
  • ease of development
  • learn one language instead of 3 or more rapidly changing languages

Overview of Python Approaches to NOJS Web Development

We call it “NOJS” web development because as Qooxdoo has shown, with Javascript, you can generate and manipulate CSS and HTML. So JS is the roots and everything else grows from there.

How shall I avoid Javascript? Let me count the ways…

There are 3 main types of offerings in the Python space for allowing yourself to develop in Python but deliver modern dynamic full-featured web applications:

  1. Transpilers – these products are primarily concerned with literal translation of Python to JSS/CSS/HTML/Web assembly.
  2. Application suites – these products are designed to abstract away most or all of the concerns of deploying an industrial strength app.
  3. Builders are somewhere in between transpilers and application suites. In most cases a builder (or transpiler) is used with a conventional terminal-server webapp framework like Flask or Django. But there can be considerable pain in integrating builder output into a full-suite web application as users of Dash used to experience but with the roll out of django-plotly-dash, this is no longer a problem with Dash.

Practical Guide

The practical guide is divided into “classes”. In many cases a Class B solution can be just as good as a Class A solution. Class A solutions are complete solutions to any functionality you might have to tackle in a world-class webapp serving hundreds of thousands of hits for thousands if not millions of users. Class B solutions solve a particular problem and do it well.

There was a recent post to reddit Python where a person needed a simple UI for uploading files and then running a process. I recommended the Class B solution Gradio and in a few lines of Python he had a nice-looking application that fulfilled the needs for him and his professor.

So Class A and Class B are excellent solutions. Class C and Class D are lacking in some facet but may still find some use.

Requirements of a Class A System

  1. that it is fully featured either directly or by easy integration with another framework that is fully featured. This requirements is in place so that people don’t get burned with a shiny short-term solution that cannot scale out to evolving requirements. Streamlit, Gradio and others are great for single-user web apps, but they do not provide a path for evolution into full-blown industrial strength web applications. In short: unless a product can directly, or with easy integration do everything in Miguel Grinberg’s Flask Mega-tutorial it is not fully featured.
  2. well-maintained – anything with no source code updates in more than 1 year cannot be considered well-maintained. If there are serious outstanding issues and pull requests this also factors in.
  3. well-documented – Ideally all major forms of documentation exist – FAQ, tutorial, Guide and Reference.
  4. Good support channels – rapid accurate response to community questions is a must.
  5. (New soft criteria) It must scale to handle 1 million requests per second or more. Cute little toy apps running on your personal Macbook pro are nice, but the world’s top 100 web properties have much higher demands for seamlessly handling large amounts of traffic. If the web solution cannot produce a site like amazon.com and handle the web traffic like amazon.com then it might be OK for building a toy app for your local barber, but it will never survive at the top level in demanding industrial situations.

Class A: Industrial Strength Rock-solid Products

In this section, we list products that are solving real-world problems and are ready for production deployment… just download, install and follow the instructions to whip out a solution to your issue PRONTO, because hundreds of other have already done the same.


http://anvil.works is an abstraction over all web development provided in a cloud web-based environment. It is a freemium product.

Someone really likes Anvil:

For me, the final choice is about productivity. Anvil isn’t an isolated tool to ‘generate HTML and JS’. It’s an integrated suite of *all the tools needed to build and deploy complete, full stack software projects, with pure Python: database and visual UI builder, server and client functionality, with essential features (user management, email, web APIs, PDF printing, Git integration and version management, Google services integration, etc.), all built in. It’s the simplicity enabled by Anvil’s overall design, the scope of its APIs, the deployment capabilities, and all the features it brings together (far beyond HTML, CSS, and JS generation), together with the breadth of capability enabled by the full Python ecosystem available natively, which makes it ridiculously productive, like no other system I’ve ever seen (writing code for 40+ years).

Built on skulpt

Anvil uses skulpt under the hood.


Turning a Jupyter Notebook into a Web App

Application Gallery

“Prototyping a YC Startup Each Day – Meter Feeder (YC Winter 16)

YC Prototypes #2: Building Magic in 2.4 hours


Panel is part of an impressive tool stack. It is focused on making visualization simple and powerful.

Built on Bokeh

Application Gallery

Awesome Panel


Dash has several eye-catching bulletpoints about it:

  • Instead of passive dashboards, one can build truly interactive analytical apps: apps can have forms and buttons to take input and update the graphical dashboard in realtime.
  • Ready for desktop and mobile and can produce print-ready PDFs on demand: has 2 (competing?) standards for responsive UI development: dash mantine and dash bootstrap.
  • there is Dash and Dash Enterprise. The enterprise version has other advanced features such as allowing an end-user to run GPU accelerated workflows to process hundreds of millions of records asynchronously.

Built on plotly and ReactJS


Ann Marie Ward has over 30 repositories with beginner and advanced Dash material. She is Co-author of “The Book of Dash“. A few highlights:

django-plotly-dash – Expose plotly dash apps as Django tags. Multiple Dash apps can then be embedded into a single web page, persist and share internal state, and also have access to the current user and session variables.

Discussion and Publications

“Pip Install Plotly-Dash | Top 10 Useful Resources for Learning / Building Dashboards within the Framework” – highly recommended video and YouTube channel.

“Dash Dashboards, Multi-Paged Quick Development with Python & React Tutorial


A quick introduction to Dash

Dash is React for Python, R, and Julia


Plotly/Dash is the Best Framework for Frontend Development IMO

Gallery of apps

From Class C to Class A

The goal is this guide is to rate frameworks that make simple web jobs simple AND allows you to scale out to develop the next top-100 web property if necessary. The class-grading-system was setup so that only highly reliable, robust AND feature-complete products were class A. At one point, Dash was nearly class C because my research revealed that one former user said:

If it’s a simple project, sure.

Otherwise it’s terrible. We switched from dash to fastapi + React. No regrets ever since.


but a recent post to reddit showed that Dash can do it all – simple things, Jupyter things and yes, top 100 web property things as well.


NiceGUI has a very clean and well-documented API and the authors have built nice deliverables on top of it such as rosys.

One of the contributors gives us a great overview of the current inner workings NiceGUI:

“No thanks Streamlit”

Streamlit is gaining major adoption in the Class B space but taking a fresh look at Streamlit revealed

it does too much magic when it comes to state handling.

The NiceGUI author provides a deeper dive into the drawbacks of Streamlit here.

built on FastAPI

The authors of NiceGUI chose FastAPI for some specific reasons even though my personal research would have me reach for Starlite. Now you can write fully featured web applications in NiceGUI.

Non-linkable anchor tags:

It is laudable that the NiceGUI website is implemented in NiceGUI itself. That being said, the anchor tags generated by NiceGUI do not have a name attribute and thus you cannot link to parts of a page generated by NiceGUI directly.

Application Gallery

Interactive images – discussion and demo link

Execute custom JS – discussion and link to demo


“NiceGUI: Let any browser be the frontend for your Python code

NiceGUI versus JustPy – very informative discussion.


https://github.com/idom-team/idom might be the quintessential builder library – it integrates with Flask, Django, FastAPI and 4 other frameworks… and the same IDOM component can run in all of these frameworks without modifications.

IDOM connects your Python web framework of choice to a ReactJS frontend, allowing you to create interactive websites without needing JavaScript!


The documentation for this project is a thorough as it gets. And they have an active discussion board. And the git repo is frequently updated. Definitely a compelling Class A approach to pure python web application development.

Built on ReactJS


In this discussion we learned that IDOM does not transpile to JavaScript. This allows pure component functions to be fully compatible and portable to any Python web framework that supports websockets.


Epyk is compatible with most common Web Python Frameworks (i.e., Flask and Django). By default, the server package embeds a Flask app as it is easier to install and ready to use.

It has good documentation and a nice gallery of working programs


Flet allows you to to build Flutter apps in Python. And that’s a big deal because

Flutter is an open source framework by Google for building beautiful, natively compiled, multi-platform applications from a single codebase.

We are talking real power here. It’s basically a corporate supported version of Htag, which is a monumental single-developer effort with similar capability. Another much older product it resembles is Muntjac, which is a port of Vaadin to Python and no longer actively supported.



Pynecone  compiles to a traditional React (NextJS flavor) app. Wrapping React components is quite straightforward. The authors had used Streamlit in the past, and found it great to get started with but for more complex apps found it limiting in terms of components, styling, and performance. In Pynecone, the frontend compiles down to a NextJS app, so you have full customizability on how the app looks. Streamlit can also be slow in some cases as it reruns the entire script on user events, whereas in Pynecone only the state deltas are transmitted. Also for performance and SEO nextjs is great.


Pynecone has excellent scalability: you can horizontally scale and connect your servers to a Redis instance so they can access the user state. The authors use FastAPI for their Python server behind the scenes for handling frontend events and sending back state deltas.

Also, when running a Pynecone app in production mode, you can use NextJS SSG to prerender the entire frontend to html.

Reference links

Application Gallery



https://github.com/fscherf/lona supports usage of Django models and the Django auth system.

To account for big HTML trees written in python, Lona supports widgets to encapsulate smaller trees an their functionalities. That makes components reusable.

Lona has an async approach which allows one to write whole views in one function and one context. The author feels it leads to much cleaner code.

According to the author Lona is based on aiohttp and uses asyncio internally. The Lona API is completely synchronous to make development easier. In contrast, with asyncio its possible to block the core event loop of the entire service without even noticing it. therefore Lona defines an API that feels like asyncio but can be integrated with blocking code seamlessly.



Nagare has earned a class A ranking. It has been around for over a decade and was one of the first frameworks to offer a pure python approach to web application development. It is very complete and their consulting firm has delivered several impressive large-scale apps. They were very supportive of me when I deployed an application to a Fortune 500 company using it. It is very much a work of art and creativity.

That being said, it has simple JS to Python transpilation only, primarily limited to the “onclick” event of a link/button..

It was inspired by the Seaside framework for smalltalk.

It is based on component-based OO instead of inheritance.

It is not designed to leverage all the power in Javascript to create reactive, highly interactive apps.

That being said, if your desire is object-oriented HTML production interfaced to an object-relational store on the back (SQLAlchemy), it is very Zen for this purpose.

It is categorized as class A because it can solve problems. It borders on Class B because it cannot offer all javascript functionality. Also, the author of nagare did not make good on his promise to integrate muntjac into Nagare. Muntjac was a Python program that brought the entire Vaadin widget set into Python, making for good-looking professional web apps.


Reahl is another tool barely hanging onto Class A rating. The main positive attribute of this framework is that it has tons of widgets out of the box for everything to do full-fledged web applications. I used it on a consulting project and did not have to look outside of it for anything.

The authors are very intelligent and responsive. I would encourage you to study it’s approach to web application development carefully before choosing it. Also read the discussion group and closed issues. To be frank, I do not see eye-to-eye with the developers on certain choices. But all in all, I have nothing but praise for how much rapid support they gave me on a corporate project I did with Reahl that was completed successfully. While both Nagare and Reahl are object-oriented super-mature systems, they embrace OO Python in drastically different ways.

Class B: Completely Acceptable Building Blocks for Some Projects

In this section, we see well-implemented, well-documented brilliant approaches to pure-python-web-dev. Note that Class B contains a number of industrial-strength “builders” and “transpilers”, meaning that even though you would not use these directly for most domains, they are what powers a currently viable Class A solution. For example, Anvil is a Class A pure-python-web-framework. But it would not be possible without Skulpt, a Class B product, under the hood.


Gradio can wrap almost any Python function with an easy-to-use user interface. The function could be anything from image enhancer to a tax calculator  but most commonly is the prediction function of a pre-trained machine learning model.

Gradio allows one to quickly create interfaces (either from the console or a Jupyter notebook or https://huggingface.co/spaces)  and `launch()` them. 

But it is also possible to customize how UI components look and/or behave.

From my perspective, the weaknesses are:

  1. It is not clear how to integrate output from Gradio into a full-blown web-app. 
  2. It offers password-based authentication only. 
  3. No support for authorization

Related Publications

Making Neural Search Queries Accessible to Everyone with Gradio

Dashboard for audio summarization, sentiment analysis, and more!” – article link

Shiny for Python

Shiny for Python has a clean API and good documentation. Like many class B solutions, it lacks the features for complete web applications – authentication, authorization and sessioning.


Htag is a very powerful and elegantly implemented pure-python-web-dev solution. It is the most recent solution by a prolific, talented and motivated author. He gained a lot of experience from his previous products, Gtag and Wyc.

The reason it is Class B is because it is a builder. A very flexible and powerful builder with the ability to be run in ALL of following deployment scenarios:

  • For a desktop app : You can use the PyWebView runner, which will run the UI in a pywebview container (or “ChromeApp runner”, in a local chrome app mode). 
  • For a web app : You can use the WebHTTP runner, which will run the UI in a web server, and serve the UI on client side, in a browser. 
  • For a android app : You can use the AndroidApp runner, which will run the UI in a kiwi webview thru tornado webserver, and can be embedded in an apk (recipes)
  • For a pyscript app : you can use the PyScript runner, which will run completly in client side

In fact any display portal which can render html/js/css, whether it be a browser, a pywebview, an android/apk, or anything based on cef, just needs an htag runner for htag to be able to render to it.

As the author states:

Yes … the promise is here : it’s a GUI toolkit for building “beautiful” applications for mobile, web, and desktop from a single codebase.



A very impressive and expressive demo once it loads.



Neutron allows developers to build native Python apps along with CSS and HTML for frontend design. Based on pywebview for it’s native GUI window and JavaScript-Python communication.


Vue.py wraps Vue.js. Vue.py is based on Brython and the author is clear about what limitations that currently imposes. The lack of a gallery of applications and small userbase lead to this being a Class B solution.

JustPy – another Vue.js wrapper


Justpy frees the developer from being concerned about the difference between front-end and back-end development. From the [README](https://github.com/elimintz/justpy):

JustPy’s backend is built using:

  • starlette – “a lightweight ASGI framework/toolkit, which is ideal for building high performance asyncio services”.
  • uvicorn – “a lightning-fast ASGI server, built on uvloop and httptools“.

JustPy’s frontend (which is transparent to JustPy developers) is built using:

  • Vue.js – “The Progressive JavaScript Framework”

The way JustPy removes the frontend/backend distinction is by intercepting the relevant events on the frontend and sending them to the backend to be processed.

I would rate JustPy over Vue.py for a Vue solution based on apparent maturity. But neither provides solutions for the common issues of a fully mature web application framework.

A recent reddit post shows the commitment of the original author to long-term support of the project. That being said, the lack of response by the author did lead to a significant fork based of JustPy based on Svelte instead of Vue.js.

Builds NiceGUI

JustPy is the library underlying NiceGUI.



And I plagiarize from the official Github:

  1. Component-based framework. Developers who have experience in using other frontend frameworks should feel quite at home when using PyFyre.
  2. Truly reactive. PyFyre’s virtual DOM allows for simple and efficient state management.
  3. Quick navigation. Navigation between pages is quick with PyFyre’s single-page application design.
  4. Pythonic code with static typing. Developing with PyFyre is much easier with its type hinting and Pythonic style of coding.
  5. Asynchronous programming. Run non-blocking functions out of the box.
  6. CPython interoperability. Developers can limitedly use CPython packages on the client-side web.
  7. JavaScript interoperability. Allowing developers to leverage NPM packages and integrate with existing JavaScript applications.
  8. Pure Python. Build web apps without ever touching other languages like HTML and JavaScript.
  9. And more!


Built on Brython


http://transcrypt.org/ is a Javascript generator that opts for integration with Javascript libraries instead of Python libraries. The book React to Python demonstrates how to use Transcrypt as the basis for full-blown applications. The sample gallery of applications is impressive. My personal nitpick is that they attempted to make some of numpy available within Transcrypt, breaking with their philosophy to leverage the Javascript ecosystem instead of Python. The clear separation of duties in a web application demands that they leave numpy and related libraries to a back-end API.

Nonetheless, Transcrypt is a polished mature product that anyone wishing the advantages of Python over Javascript is encouraged to use as a DSL for Js/Css/HTML.

By no means should you think every single aspect of CPython is available in Transcrypt: their docs tell you otherwise:

Note that Transcrypt avoids constructs that cannot be made to perform in the browser. This means that Transcrypt and CPython are playing in different leagues. Transcrypt makes it possible for Python programmers to take a lot of their skills to the browser, but it is in no way a replacement for CPython. The two should be regarded as complementary.

Transcrypt documentation.


Zython is a webassembly project with a completely different implementation than python-wasm and pyodide, which are both based on emscripten and therefore suffer certain drawbacks that zython is not limited by.

The stated goal of the project is “…to create a WebAssembly build of the core Python and dependent packages, which runs both on the command line with Node.js and in the major web browsers (via npm modules that you can include via webpack). “

I find it unfortunate that the package name python-wasm ` is used in this project: it seems like it creates un-necessary confusion.

Discussions and articles


With Bokeh, you can create JavaScript-powered visualizations without writing any JavaScript yourself. It is also possible to use Bokeh output in traditional frameworks like Django or Flask.

For me, the big question is: what good is a solution that is focused only on abstracting javascript visualizations? Aren’t there other things you can use Javascript for? Why would I choose this when I’m going to need another solution for other Javascript concerns?

The answer lies in the holoviz framework, which provides programmatic access to Bokeh and more.



Python with the scientific stack, compiled to WebAssembly.

Pyodide may be used in any context where you want to run Python inside a web browser.

Pyodide brings the Python 3.9 runtime to the browser via WebAssembly, along with the Python scientific stack including NumPy, Pandas, Matplotlib, SciPy, and scikit-learn. Over 75 packages are currently available. In addition it’s possible to install pure Python wheels from PyPi.

Pyodide provides transparent conversion of objects between Javascript and Python. When used inside a browser, Python has full access to the Web APIs.

Building Block for

It is what PyScript is built on.






https://pywebio.readthedocs.io/en/latest/ is a builder with documented integration for Tornado, Flask, Django and aiohttp. It can also execute standalone. It is surprisingly procedural, yet offers decent support for nested rendering using functions instead of objects and methods.

Sample code

Tokyo Olympics country’s performance ranking

Skulpt and Brython

are both in-browser Python implementations. But they have different objectives as well as strength and weaknesses. Brython is faster. However Skulpt requires slower execution and load times because it aims for full python compliance. The objective of the products is different: Brython is aiming to be a replacement for Javascript while Skulpt aims to be a Python distribution that has a web browser execution target.

i found a nice chart on this site as well as this site. I dont know who is plagiarizing from who, but the table does give a nice overview of the various low-level solutions;

Related Reading

  • https://www.reddit.com/r/Python/comments/2yli88/whats_the_best_implementation_of_a_python/



Building block for….

Skulpt is what Anvil, a Class A pure-python-web-dev solution is based on.


PyWeb3D allows you to use the three.js library without writing a JavaScript. As I voiced in my review of Bokeh, one wonders what to do when needing to abstract other aspects of Javascript/HTML/CSS.

Built on: Brython

Articles and Applications

Meet PyWeb3D — Three.js With Python Syntax



Reacton – A pure Python port of React for ipywidgets

 ipywidgets is a library for writing interactive widgets in the Jupyter notebook.

Reacton is a pure Python library, that implements a similar API as ReactJS. Instead of rendering to the DOM, it renders to ipywidgets. The ipywidget library is then responsible for rendering in the front end (which could use ReactJS, Vue, or even jQuery).



https://streamlit.io/ is very powerful and very popular, but adding features that you expect in a full-blown web app is hard and hackish or messy depending on who you talk to. However, apparently they have been bought out by Snowlake so they have a strong backing moving forward.

Application Gallery

Made a Streamlit app to show demographic breakdowns by age, race, gender, and education in the biggest 100 US metro areas.”

Streamlit for Machine Learning Cheat Sheet

How to Build a Dividend Investing Dashboard in Python and Streamlit

NFT and Metadata Generator – Python & Streamlit

I created a Streamlit UI for OpenAI’s Whisper and added some basic scaffolding for transcript summarization


“Easy Monitoring of dbt Cloud jobs with Streamlit “

Plotting all public transport in NL livestream using Streamlit

I was unhappy with Spotify recommendations, so I used Python+Spotify’s API to make more than 1,000. See the bottom from a Streamlit app to find your playlist.”

SQL Formatter




New Streamlit tutorial, 68 pages, 35 minimal app examples, focus on SQL+Streamlit”

Build Real-time Data Applications Quickly Using Streamlit And Prisma


I was excited about YOLOv7, so I built a sharable object detection application with VDP and Streamlit.

Streamlit User and API Authentication with Auth0 Next.js SDK

Class C: Solutions with Severe Limitations

This section covers products with limited scope


Enaml web is part of a very broad ecosystem:

  • There is plain old Enaml which can succinctly build desktop applications using their python-powered DSL
  • There is Enaml-web which is a variant of Enaml for the web
  • There is atom-db, which is their asynchronous ORM
  • And there is Atom, which is a very capable object system for Python. Their object system has observers and data validation. It is almost as good as Traitlets, which is slightly more powerful because you can generate command-line interfaces from Traitlets classes easily.

Enaml-web has a couple of demo projects. Why is it class C?

  • you can do the simple things that it can do with simpler tools and less code
  • no roadmap or facilities to do complex world-class web apps
  • the user base is apparently small
  • the developer base is apparently small
  • to it’s merit, the code is frequently updated
  • very few real world examples. just two sample projects


PyScript is developed by Anaconda. Superficially, and only superficially, PyScript seems to be just like Brython – you embed Python in some tags in HTML and walla, dynamic web pages with Python not Javascript.

But PyScript sets itself apart from Brython because it is based on Pyodide. In the words of the co-author:

Pyodide is the same *CPython* interpreter you run on your laptop, but compiled to target WebAssembly. (Just as CPython is compiled to target x86 or M1 assembly on your laptop.)

This is why the various native C/C++ extensions for Python can also be supported: they are compiled to target WebAssembly as well.

This has nothing to do with Javascript. It’s certainly not the case that “Pyodide is Python written in JS” — that is more like Brython. (Such an approach could never import numpy, pandas, scipy, etc. without also rewriting all of those in Javascript as well.)

Peter Wang, CEO of Anaconda

Since Anaconda has already developed Panel, one would wonder why PyScript. Wang states: 

This is a broader and more fundamental capability than Panel. You can run just about any Python in the browser. And you can wrap Javascript libraries. So we have examples showing interaction with Three.JS, with d3, etc.

According to Wang, the intent of PyScript is:

… to empower programming for millions of people who find existing stuff too complex. Learning even a single language is hard enough. These folks will not be able to learn all the complexity of JS, modern web dev and devops, etc etc.

With PyScript, they just write in a single language, with a little bit of HTML, and they have something that they can share with any friends and colleagues, with zero deployment complexity. They can email them the file, or copy it on a thumb drive.

Peter Wang, CEO of Anaconda

Currently the interest in PyScript far outstrips its ability to offer a productive solution to prospective users. However, the strong corporate backing and large team of developers for the product indicate that it may well be a Class A system in the next year or so. It has tremendous potential. As the author of htag has stated:

This thing is the most incredible thing I’ve seen for some years … In the JavaScript and python world

It opens/unlocks a lot of things …

Coming from brython, it unlocks full python … In the right way (thanks wasm)

Sure, there are a lot of improvements/gaps, before it could be supported natively in VM browsers … But it’s the way to go …

But the promise is here … You can code python (and pip any libs you want), with just a js include … For now ! Can’t imagine all the things which will come soon … Pretty excited !



Can you pass objects between JS and Python?

Passing objects is supported. In the OpenAI API example, you will see js -> py with:

from js import localStorage, document, console, XMLHttpRequest

  • from js import…” imports js objects directly into PyScript’s Python.

Going in the other direction (py -> js), you can use PyScript.runtime.globals.get('my_variable_name')

XMLHttpRequest is what I used to make the HTTP requests as requests is not supported. An alternative would be to use pyodide.http.pyfetch




Related Publications

Built on pyodide


UIdom official repo

Built on dominate


And I plagiarize:

Gooey converts your Console Applications into end-user-friendly GUI applications. It lets you focus on building robust, configurable programs in a familiar way, all without having to worry about how it will be presented to and interacted with by your average user.


Because as much as we love the command prompt, the rest of the world looks at it like an ugly relic from the early ’80s. On top of that, more often than not programs need to do more than just one thing, and that means giving options, which previously meant either building a GUI, or trying to explain how to supply arguments to a Console Application. Gooey was made to (hopefully) solve those problems. It makes programs easy to use, and pretty to look at!

Who is this for?

If you’re building utilities for yourself, other programmers, or something which produces a result that you want to capture and pipe over to another console application (e.g. *nix philosophy utils), Gooey probably isn’t the tool for you. However, if you’re building ‘run and done,’ around-the-office-style scripts, things that shovel bits from point A to point B, or simply something that’s targeted at a non-programmer, Gooey is the perfect tool for the job. It lets you build as complex of an application as your heart desires all while getting the GUI side for free.


per the Wooey docs:

Wooey is a simple web interface to run command line Python scripts. Think of it as an easy way to get your scripts up on the web for routine data analysis, file processing, or anything else.


It breaks my heart to put Remi in the Class C section. The author works very hard on his product and is very responsive.

It offers a class-based approach to user interface generation. It operates using an internal webserver and has limited support for traditional authentication and authorization.

It primarily is good at building user interfaces for personal use. It is far older than Gradio.


Abstracloud reminds me of Gradio but with commercial restrictions. The pricing model and non-FOSS distribution method seem to be a bit limiting. For instance, comparing their pricing model with Anvil’s, we see that we can have 50,000 data table rows in the free account at Anvil whereas any storage requires a jump up to the paid plan.




https://github.com/atsepkov/RapydScript is a Class C system primarily because it is not Python and it is not Javascript. They do have an impressive set of gallery examples but the mailing list and source code have no activity since May 2021. When one attempts to make a new language, one must first have users as well as libraries and if there is any attrition in either, then the language becomes less desirable over time. We’ve seen it happen with Coffeescript as well as Cappucino and Objective-J. To be sure, Python has warts and Javascript has even more warts but I once saw an IRC chat where someone was arguing about rewriting Emacs in Common Lisp and the other person said: “your opinion is no substitute for millions of lines of working code”. In other words, a perfect language is nothing without libraries an userbase.

Rapydscript-ng – a fork of RapydScript

https://github.com/kovidgoyal/rapydscript-ng is a fork of the Rapydscript ng. there have been no commit to the repo since Dec 2021. To fork a language to create even another variant means that rapydscript-ng shares the same hazards of adoption as Rapydscript itelf

Ryact and Breact

Ryact and Breact are emulations of react. Ryact is built on rapydscript and is 10x faster than Breact, which is built on Brython. As a single author, he has not been able to keep up with all the demands of industrial-grade software engineering in his projects.

Built on rapydscript and Brython

WASMer for Python: Pyodide’s little brother?

https://github.com/wasmerio/wasmer-python – is a WebAssembly runtime for Python. It seems to have less popularity as a builder than Pyodide. Also the development team and userbase appear to be smaller.


Domonic is a builder also. It contains quite a few sub-packages, some of which might be better elsewhere:

  • html : Generate html with python 3 ????
  • dom : DOM API in python 3 ????
  • javascript : js API in python 3 ????
  • terminal || cmd : call terminal commands with python3 ???? (see at the end)
  • JSON : utils for loading / decorating / transformin
  • SVG : Generate svg using python
  • aframe || x3d tags : auto generate 3d worlds with aframe.

The author also has a stripped down package called htmlx that will be discussed in the HTML only section.

Why is Domonic rated so low?

Well, the doc and the source code repo are very current, so that cannot be why. Basically it is an unfinished project with very few deliverables. For example in the docs about the d3 interface, he states ‘WARNING: this package is still in dev. expect bugs ‘. The approach to pure Python web development seems a bit less elegant than other projects. For instance, the need to manually wrap d3 and then do an incomplete job of it shows how much more limited this project is than Transcrypt which can use any Javascript library without any particular wrapping.

The author also developed htmlx, which is a stripped down version of domonic, limited primarily to rendering HTML.


https://h2oai.github.io/wave/ is good at building realtime streaming dashboards. It has support for OpenID and Basic Auth but has no examples or express concern for integration with Flask or Django, even though they feel it probably should work.

I installed Wave and played around with the tour. I had problems getting some of the examples to work on Windows. Even so, I find Wave to be very succinct and very powerful.

It is modular and dynamic. By modular, I mean, that building a website is as simple as populating Python data structures with objects. By dynamic, I mean I was impressed by the ability to edit a live website directly from the Python REPL. Just think: a live site could have updates from cron jobs.

I was a bit put-off by having to learn two different ways to use Wave: one for scripts and one for apps. To make things simple for myself, I would just always write apps. Also, the tutorial would do well to have 2 directories – one for scripts and one for apps instead of putting all Python examples in an apps directory.

I also did not like the way to model was initialized in the rendering method. I started a discussion about that.

Class D: Defunct products

This section keeps track of products that are no longer maintained and may not address modern web application development concern.


It may be a bit harsh to classify Dashborg as defunct. But the slack invite link is not working and the repos do not have recent commit. in fact, the main dashborg product is not FOSS, only the back-end SDKs are. The userbase appears small and there are no documented real-world use cases.

https://www.dashborg.net/ is unique. You could call it a more sane approach to the nightmare that Angular is. It allows one to create full applications but using a “live” version of HTML that dynamically self-populates using either Go or Python back-ends.

It is interesting, but it works backwards from the way I think: I would rather have a computer program generate HTML/JS/CSS rather than have my turing-complete language limited by what I can stick into HTML.

So I would say it would not interest me much in the same way that Angular does not – the less powerful language is orchestrating the use of a more powerful language.

Other past tools in this vein are OpenLaszlo. A current popular tool like this is HTMX.


Muntjac is an implementation of Vaadin for Python. Vaadin is an enterprise level Java web app framework with a large array of modern clean javascript widgets.

While Vaadin abstracted away Javascript through Java, Muntjac did the same for Python in an impressive way.

Timothy Crosley Products


https://github.com/timothycrosley/WebBot is

a collection of 

several tools that enables building Python web applications 

the same way native ones are built. 

As a result, the WebBot framework encourages reuse, 

concise code, rapid development, and happy developers.


Jigna showed great promise in it’s EuroPython 2014 talk. Being based on Enthought Traits and supported by Enthought are also feathers in its cap. However, the source code repo has seen no action for 3 years now, landing it in the defunct category.


https://github.com/timothycrosley/jiphy is a nearly-defunct transpiler.


https://github.com/timothycrosley/thedom is for generating HTML and JS


https://www.anpylar.com/ has seen no updates since 2018.

PyJS (formerly PyJamas)

http://pyjs.org/ used to be called PyJamas but that name has been reserved for something altogether different now.


  1. fast html
  2. html write
  3. Messy Soup
  4. Htmlx is a stripped down version of a larger package named domonic written by the same person. Discussion.
  5. https://github.com/BrainStormYourWayIn/sierra
  6. Perry https://www.reddit.com/r/Python/comments/roaz0i/fancy_way_of_writing_websites_perry_library/
  7. https://github.com/Knio/dominate
  8. https://pypi.org/project/simple-html/


React in Python –

IDOM vs. Transcrypt (Ryact and Breact omitted)

Both IDOM and Transcrypt have solutions for using React purely in Python. However because IDOM does not transpile to JavaScript, pure component functions are fully compatible and portable to any Python web framework that supports websockets.

enter Pynecone

Pynecone is a new project that compiles to the NextJS flavor of react it has an impressive gallery.

Tangential Products


React is now available in ipywidgets thanks to Reacton


py-react supports running Python in the browser via Pyodide. That being said, it does not appear to be aspiring to be a web application toolkit like other python-in-the-browser products (skulpt, brython, pyscript). Thus py-react is listed here in the tangential section. You may try it out here.

Discussion threads for this product:

Compelling Non-Python Products


UrWeb is a single, strongly-typed language that compiles into a single binary that can issue SQL and Javascript.


Vaadin is a java-based product with tons of widgets that allows a Java developer to have all the interactivity with none of the headache of dealing with Javascript.


Many people who wish to remain in Django/Flask land opt for HTMX to give them the power of Javascript .

Frequently Asked Questions (FAQ)

Any impressive apps built with these technologies?



“Easy Monitoring of dbt Cloud jobs with Streamlit “

2 thoughts on “Pure Python Web Application Development – NO CSS, HTML, or Javascript needed or wanted!

  1. Hi aCadfwe, beeware does not produce web applications does it? It is for android/ios/desktop… kind of like kivy.

    It’s an interesting topic that we could have a survey for. But I think that would be another survey document.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top