3 min read

Run Python without installing anything

A real CPython interpreter in the browser via Pyodide — a working snippet, when a browser REPL is the right tool, and how the sandbox actually protects you.

pythonwebassemblytoolsapps

Sometimes you just need to run a few lines of Python and you are on a machine with no Python, or you do not want to touch its install for a thirty-second job. Python is CPython itself, compiled to WebAssembly by the Pyodide project, with the full standard library along for the ride — not a transpiler, not a faked subset. Your code and its output never leave the page.

A snippet that actually does something

Here is a sieve of Eratosthenes and a quick use of it — comprehensions, a set, slicing, all the things that make it Python:

def primes_below(n):
    sieve = bytearray([1]) * n
    sieve[0:2] = b"\x00\x00"
    for i in range(2, int(n ** 0.5) + 1):
        if sieve[i]:
            sieve[i*i::i] = bytearray(len(sieve[i*i::i]))
    return [i for i, is_p in enumerate(sieve) if is_p]

ps = primes_below(50)
print(ps)
len(ps)

You get the printed list on stdout, and because the last line is a bare expression, the REPL shows its value the way a real prompt would — the count of primes. Raise an exception anywhere and a genuine traceback comes back, not a vague error string.

A data transform without a virtualenv

The standard library is right there, so the everyday one-off reshaping works with no install:

import json
from collections import Counter

rows = [
    {"user": "ada", "event": "login"},
    {"user": "ada", "event": "click"},
    {"user": "linus", "event": "login"},
]
counts = Counter(r["user"] for r in rows)
print(json.dumps(dict(counts), indent=2))

That is the sort of thing you would otherwise open a notebook or a scratch file for. Here it runs in the tab.

When a browser REPL is the right tool

It is the right tool when the cost of setting up is larger than the job: checking what a snippet from documentation actually does, confirming an edge case in the standard library, working out a tricky comprehension, teaching or learning with nothing to configure. It is the wrong tool when you need packages with compiled native extensions that Pyodide does not carry, when you are moving gigabytes of data, or when the work has to plug into a real project's environment. For a self-contained few dozen lines, though, it starts faster than a fresh virtualenv.

The sandbox model, honestly

The interpreter runs inside the browser's WebAssembly sandbox. That means it cannot reach your filesystem, cannot open network sockets, and cannot touch anything outside the page — the same isolation that lets you run a snippet you only half-trust without worrying what it does to your machine. The trade is the mirror image: it has no filesystem or network to offer your code either, so a script that expects to open a local file or hit an API will not find one.

The runtime is about 12 MB and downloads the first time you open the app; the browser caches it, so after that it starts quickly and runs offline. Nothing you type is posted anywhere — it is a genuine scratch interpreter, not a form that ships your code to a server.

Try it

More writing