Running Python ASGI apps in the browser via Pyodide + a service worker
Simon Willison demonstrates how to run full Python ASGI applications (like FastAPI and Datasette) in the browser using Pyodide and a Service Worker, eliminating the need for a backend server and revealing the viability of frontend Python apps.
- Core Tech: Uses Pyodide (WebAssembly Python) and a Service Worker to intercept browser requests and execute Python apps client-side via the ASGI protocol.
- Solved Previous Pain Point: The older Web Workers approach couldn't execute JavaScript within <script> tags, breaking app functionality (e.g., Datasette plugins).
- Demonstrated Generality: Successfully demoed both FastAPI and the full Datasette 1.0a31 app, proving the method works for typical ASGI frameworks.
- Development Paradigm Shift: Transforms a traditional server-side Python app into a "serverless" frontend application that runs entirely in the user's browser.
The Context: A New Solution to an Old Problem
Four years ago, Simon Willison created Datasette Lite, a version of Datasette running in the browser via Pyodide. That initial approach used Web Workers to intercept requests and run Python to generate HTML. However, it had a critical flaw: JavaScript code inside <script> tags on the page wouldn't execute, breaking core Datasette functionality and many plugins. This pain point persisted until recently, when he tasked Claude Opus 4.8 (in Claude Code for web) with exploring an alternative using Service Workers instead of Web Workers—and it worked.
The Breakdown: How a Browser Becomes a Python Server
The essence of this approach is to "trick" the browser into thinking it's communicating with a backend server, while all processing happens client-side. Pyodide compiles the Python runtime into WebAssembly, enabling Python execution in the browser. The Service Worker acts as a "network interceptor." When a user navigates to any URL under the /app/ path, the Service Worker intercepts the network request. Instead of fetching a response from a remote server, it "feeds" the request to the Python ASGI application running inside Pyodide. ASGI (Asynchronous Server Gateway Interface) is the standard interface for modern Python web frameworks like FastAPI and async Django. The app processes the request, generates a response, and the Service Worker returns that response to the browser. The entire process requires no remote backend server after the initial load of static files (HTML, JS, Pyodide itself).
Trend Insights: The Frontend Boundary is Dissolving, and Python's Web Role is Redefined This project reveals several deeper trends. First, the ultimate form of 'serverless' might truly be 'serverless'—not even cloud functions are needed, with logic running entirely on the client. This opens doors for offline apps, zero-backend-cost prototypes, and privacy-focused data processing tools. Second, WebAssembly is becoming a universal cross-language runtime. Not only can Rust and C++ run performantly in the browser, but now Python and its rich ecosystem (like data analysis libraries) can also be used on the frontend with acceptable performance. Third, AI coding assistants (like Claude) are becoming 'accelerators' for exploring complex tech integrations. Willison directly delegated the research to an AI, demonstrating AI's effectiveness in solving complex engineering problems that require combining multiple technologies (Pyodide, Service Worker, ASGI). Finally, Python's traditional role as a 'glue language' is extending into the browser. Developers can write backend logic in familiar Python and FastAPI, then deploy it directly as a pure frontend application, blurring the traditional front-end/back-end divide.
Practical Value: What Does This Mean for You? For developers, this provides a powerful new toolbox. You can build Python web apps that require absolutely no servers or domains—ideal for internal tool demos, teaching environments (where students don't need server setup), or client-side tools for sensitive data (data never leaves the browser). For users of Datasette or similar data exploration tools, future versions of Datasette Lite will have full functionality, including all plugins. It also means you can try right now: write a simple API with FastAPI and package it into a single-file HTML app using this method. Of course, there are limitations: the first load requires downloading several megabytes for Pyodide and the Python runtime, and it's unsuitable for scenarios requiring heavy computation or database access. But for many utility and presentation apps, this is a disruptive, lightweight deployment option.
Counterintuitive/Unexpected Insights One point that might be overlooked is that the "driving force" behind this solution was AI. Willison didn't钻研 the complex interactions of Service Workers and ASGI himself; instead, he clearly described the problem and handed it to Claude Opus 4.8. This demonstrates a new workflow: humans define the problem and architecture, while AI handles implementation and integration. Another surprise is that this seemingly "hacky" approach has unexpectedly good generality, capable of running the full Datasette application. This hints at the elegance of the ASGI protocol design and the maturity of Pyodide—perhaps more suitable for production environments than we might think.
Analysis by BitByAI · Read original