jackmckew.dev drafts preview
← All posts
Python

Running Python in the Browser with Pyodide

\n\n\n \n \n
\n\n    \n\n\n```\n\nThat works. You can paste Python and run it. Load the page, type code, hit the button.\n\nNow the real stuff - building an interactive app. I built a CSV uploader and data explorer:\n\n```html\n\n\n\n\n\n\n
\n\n\n```\n\nThe JS-Python bridge is where things get weird but also powerful. You can pass objects back and forth:\n\n```javascript\n// JavaScript calling Python\nlet result = pyodide.runPython(\"2 + 2\"); // returns 4\n\n// Python returning values\nlet output = pyodide.runPython(`\n data = {'name': 'Jack', 'age': 30}\n data\n`);\nconsole.log(output.toJs()); // { name: 'Jack', age: 30 }\n\n// Python calling JavaScript\npyodide.runPython(`\n from js import console\n console.log(\"Hello from Python!\")\n`);\n```\n\nI built a simple calculator interface:\n\n```html\n\n\n\n\n

\n\n\n```\n\nThis is where I expected it to break. But it... doesn't. You can pass variables from JS to Python, do actual computation, get results back.\n\nHere's the honest part though: the trade-offs are real.\n\n**Load time is brutal.** The first time you load the page with Pyodide, it downloads ~50MB of WebAssembly and CPython. Subsequent loads are cached, but first-time users wait 10-15 seconds. Not ideal for a marketing site, but fine for internal tools or shareable analysis notebooks.\n\n**Not all packages work.** NumPy is there. Pandas is there. But packages that need C extensions sometimes don't have WASM builds. scikit-learn works but it's chunky. TensorFlow? No. You're limited to the curated ecosystem.\n\n**No multithreading.** Python's GIL is... still a thing. Heavy computation blocks the browser tab. Do a 30-second calculation and your app freezes. You can work around it with JavaScript workers but that's annoying.\n\n**File size matters.** Every package you import adds to the runtime overhead. A minimal Pyodide is ~10MB, but if you load pandas you're at 30MB+.\n\nBut here's why it's worth it: **you can ship interactive tools with zero backend infrastructure.** You don't need servers, databases, API keys, authentication. Upload the HTML file to GitHub Pages and users can run Python directly in their browser. For specific use cases - data exploration, calculators, format converters, equation solvers - this is genuinely powerful.\n\nI used it to build a frequency analysis tool for analyzing English text. Users paste text, the browser runs character frequency counts, and outputs a histogram. All client-side. You could never scale this with a traditional backend (per-user computation), but with Pyodide it's essentially free - your compute is the user's computer.\n\nThe mental model is: if you can do it in a Jupyter notebook, you can probably deploy it as a Pyodide app. The latency sucks on cold load but once it's running it's fast.\n\nReal use case that sold me: a colleague needed to validate CSV data against a schema before uploading to a system. Instead of building an API, I wrapped the validation script (200 lines of Python) in a Pyodide app. Sent him a link. It works offline. No backend needed. That's the win.\n\nTry it if you have a Python script that could be useful as a shareable tool. The barrier to shipping is basically zero."; document.getElementById('content').innerHTML = marked.parse(raw); document.querySelectorAll('pre code').forEach(el => hljs.highlightElement(el));