Inspiration

Writing Python that runs inside a web page usually means fighting with Pyodide's verbose API. You have to manually load scripts, create output divs, bind events, and convert data types. For example, a simple "print hello" requires 10+ lines of JavaScript glue code.

I wanted a zero-boilerplate way: write Python directly inside your HTML, using the same <script> tag you already know from JavaScript. That's why I built Pytml.

What it does

Pytml lets you embed Python code inside an HTML page with no extra syntax. Just write:

<py>print("Hello from Python")</py>

It automatically: Sets up the Python runtime (via Pyodide, for now)

Captures print() output and sends it to the DOM

Lets Python read/write HTML input values using native Python syntax

Works with static hosting – no server required

You can build interactive widgets, calculators, or data visualizations using pure Python + HTML.

How we built it Core: JavaScript (ES6) that dynamically loads Pyodide and wraps it in a DOM-based API.

Parsing: A custom script that scans the HTML for , , and tags.

Bridging: Python's sys.stdout is captured and redirected to a DOM element.

AI use: I used GitHub Copilot only for debugging edge cases (e.g., race conditions when Pyodide loads slowly). All architectural decisions are my own.

Challenges we ran into The hardest part was preserving Python's native syntax while making it talk to the browser. For example, I wanted you to be able to write:

name = input("What's your name?")
print(f"Hello {name}")

…and have it show a real HTML prompt, not a terminal one. That meant intercepting input() and print() at the C-level via Pyodide's pyproxy – a deep dive into how Python's builtins work.

Another challenge: making sure Python variables persist across multiple blocks without leaking memory.

Accomplishments that we're proud of True syntax compatibility – Pytml runs existing Python scripts without modifications (except for DOM-specific things).

Live demo – pytml.vercel.app shows a working calculator and a data plotter in under 5 lines of code.

Lightweight – The wrapper script is under 15KB minified; Pyodide loads only when needed.

First hackathon submission – And it already has a working MVP with 100+ commits.

What we learned Pyodide is powerful but not beginner-friendly. I learned:

How Python's sys.stdout and sys.stdin can be overridden at runtime.

The difficulty of synchronously waiting for async WebAssembly operations (spoiler: you can't – you need callbacks everywhere).

Why no one has made a truly simple "Python in HTML" tool before – the edge cases are brutal.

But that's exactly why this project excites me.

What's next for Pytml Phase 1 (current) – Use Pyodide as the backend. Stable, but slow to load (~10-15 MB).

Phase 2 (next 3 months) – Replace Pyodide with a custom Wasm-compiled Python interpreter (micro-python or a stripped CPython). This will cut load time from seconds to milliseconds.

Phase 3 – Add support for Python packages like numpy and matplotlib (via Wasm builds).

Long term – A VS Code extension that lets you preview .pytml files live, and a CDN that caches the runtime globally.

Built With

Share this project:

Updates