HTMX vs WASM

more backend or more frontend?

Get the slides: slides.com/cheukting_ho/htmx-vs-wasm/

Hello I am Cheuk

  • Open-Source contributor


     
  • Organisers of community events


     
  • PSF director and fellow
     
  • Community manager at OpenSSF

Who has heard of Project Iodide?

Project Iodide

  • Mozilla's trial project
  • Build Scientific tools and interactive docs
  • Uses the power of modern browsers
  • Not Jupyter - no backends
  • Not Python specific - JSMD (JavaScript MarkDown)
  • Sunset in September 2020

WASM

Looks cool

to do that we need

What is WASM?

Your computer

  • a CPU chip
  • machine code
  • C compiler
  • CPython
  • Python

Web Browser

  • virtual machine
  • WASM
  • Emscripten
  • Pyodide
  • Python

Why project Iodide was not more popular?

Problems with Iodide

  • Not adopting as well as Jupyter
  • Support mainly by one organisation
  • Leads to sunset in 2020
  • Also leads to spin out of Pyodide
  • A community-run project

We are in the age of Python on browser

Pyodide enable

  • Running Python code in browser
  • Install and run Python packages in browser
  • Run Jupyter notebook in the browser - JupyterLite
  • Build frontend application with Python on the browser - PyScript

PyScript

  • a framework
  • run Python applications in the browser
  • access to DOM
  • multiple backends - Pyodide / MicroPython
  • many popular packages of Python available
    (Thanks Pyodies)
  • Playground at pyscript.com
<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8" />

        <title>Todo App</title>

        <link rel="icon" type="image/png" href="favicon.png" />
        <link
            rel="stylesheet"
            href="https://pyscript.net/latest/pyscript.css"
        />

        <script defer src="https://pyscript.net/latest/pyscript.js"></script>
        <link rel="stylesheet" href="./assets/css/examples.css" />
    </head>

    <body>
        <nav class="navbar" style="background-color: #000000">
            <div class="app-header">
                <a href="/">
                    <img src="./logo.png" class="logo" />
                </a>
                <a class="title" href="" style="color: #f0ab3c"
                    >Pyscript Native TODO App</a
                >
            </div>
        </nav>
        <section class="pyscript">
            <h1>To Do List</h1>
            <py-tutor modules="utils.py;pylist.py">
                <py-register-widget
                    src="./pylist.py"
                    name="py-list"
                    klass="PyList"
                ></py-register-widget>

                <py-config>
                    plugins = [
                      "https://pyscript.net/latest/plugins/python/py_tutor.py"
                    ]
                    [[fetch]]
                    files = ["./utils.py", "./pylist.py"]
                </py-config>

                <py-script>
                    from js import document
                    from pyodide.ffi.wrappers import add_event_listener

                    def add_task(*ags, **kws):
                      # create a new dictionary representing the new task
                      new_task_content = Element("new-task-content")
                      task = { "content": new_task_content.value,  "done": False, "created_at": dt.now() }

                      # add a new task to the list and tell it to use the `content` key to show in the UI
                      # and to use the key `done` to sync the task status with a checkbox element in the UI
                      myList.add(task)

                      # clear the inputbox element used to create the new task
                      new_task_content.clear()

                    def on_click(evt):
                      add_task()

                    def handle_keypress(evt):
                      if evt.key == "Enter":
                        add_task()

                    add_event_listener(
                      document.getElementById("new-task-content"),
                      "keypress",
                      handle_keypress
                    )
                </py-script>
                <div class="py-box">
                    <input id="new-task-content" />
                    <button
                        py-click="add_task()"
                        id="new-task-btn"
                        class="py-button"
                    >
                        Add Task!
                    </button>
                </div>

                <py-list id="myList"></py-list>
                <py-repl id="my-repl" auto-generate="true"> </py-repl>
            </py-tutor>
        </section>
    </body>
</html>

The frontend is getting

thicker and thicker

Is this what we want?

There are limitations:

  • loading time
     
  • RAM in the browser VM (4GB)

What about we make it thinner?

How about just HTML?

HTMX

On the other hand,

we have another movement

Using HTMX

  • Forget about JavaScript
  • Easily adding dynamic elements in HTML
  • Lighter than React
  • Everything in one place

Using Django with HTMX

Using Django with HTMX

  • CSRF security token needed
  • HTMX elements in template
  • dynamically change the page
  • plug-in like django-htmx
<html>
  <head><title>Htmx Demo!</title></head>
  <body>
    {% block main %}{% endblock %}
    <script src="https://unpkg.com/htmx.org@1.1.0"></script>
    <script>
      document.body.addEventListener('htmx:configRequest', (event) => {
        event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}';
      })
    </script>
  </body>
</html>

base.html

<div id="tasks"
  hx-confirm="Are you sure you want to delete this task?"
  hx-target="#tasks"
  hx-swap="outerHTML">
  {% for task in tasks %}
    <div>{{ forloop.counter }} {{ task.description }}
      <a class="block mr-2 hover:text-gray-600"
        hx-delete="{% url 'delete_task' task.id %}">
        Delete?
      </a>
    </div>
  {% endfor %}
</div>

display_tasks.html

So what will it be like in the future?

My wild guesses...

  • JavaScript no longer needed for frontend work
  • JavaScript will be considered "low level"
  • More casual coders
  • More integration with AI models

HTMX vs WASM more backend or more frontend?

By Cheuk Ting Ho

HTMX vs WASM more backend or more frontend?

  • 323