Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →To run Python from an HTML page, load a browser Python runtime such as Pyodide, wait for it to initialize, then call Python code from JavaScript with pyodide.runPython(). The page still uses HTML and JavaScript; Pyodide supplies the Python runtime. This guide uses Pyodide for a direct, copyable setup and explains when PyScript or Brython may fit better.
Run Python in an HTML page with Pyodide
Save this as index.html and open it from a local web server. It loads a versioned Pyodide distribution, waits for initialization, executes Python, and displays the returned value in the page.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Python in the browser</title>
</head>
<body>
<h1>Python in the browser</h1>
<button id="run" disabled>Loading Python…</button>
<pre id="output">Starting runtime…</pre>
<script src="https://cdn.jsdelivr.net/pyodide/v314.0.7/full/pyodide.js"></script>
<script>
const button = document.querySelector("#run");
const output = document.querySelector("#output");
let pyodide;
async function startPython() {
try {
pyodide = await loadPyodide();
button.disabled = false;
button.textContent = "Run Python";
output.textContent = "Python is ready.";
} catch (error) {
output.textContent = `Could not start Python: ${error.message}`;
}
}
button.addEventListener("click", () => {
try {
const result = pyodide.runPython("1 + 2");
output.textContent = `Python returned: ${result}`;
} catch (error) {
output.textContent = `Python error: ${error.message}`;
}
});
startPython();
</script>
</body>
</html>
The versioned CDN path follows the Pyodide stable guide’s version context, which was listed as 314.0.7 when checked on September 29, 2026. Pinning a version makes deployments more reproducible; check the current usage guide before choosing a version for a new project. Do not substitute a development CDN URL for a deployed application.
What happens in the example
- The script tag loads
pyodide.js, which exposesloadPyodide(). startPython()is asynchronous and awaitsloadPyodide(). The button remains disabled until setup succeeds, preventing a call before the runtime exists.pyodide.runPython("1 + 2")executes Python and returns a value that JavaScript can use.- The event handler catches Python errors and presents their message in the page instead of silently failing.
To run more than a one-line expression, pass Python source as a string. For example, replace the call with pyodide.runPython("total = sum([2, 3, 5])ntotal"). The final expression’s value is returned to JavaScript. For larger programs, keep the source in a separate file or a template string so it is easier to maintain.
#1 Best Overall
Use Python variables and functions from JavaScript
Python names created in the runtime’s global scope can be accessed through pyodide.globals, as described in the Pyodide quickstart. For example, run Python that defines answer = 42, then read it with pyodide.globals.get("answer"). When you are finished with a Python value, follow Pyodide’s guidance for releasing proxies where applicable; values crossing between Python and JavaScript do not always behave like ordinary native JavaScript values.
Serve the page over HTTP during development
A simple page that only loads its runtime may appear to work when opened as a file, but browser security restrictions make file:/// an unreliable way to load local data files. If your Python code needs files, serve the project over HTTP instead. For example, with Python installed, run python -m http.server 8000 in the directory containing index.html, then open http://localhost:8000/.
This starts a basic development server; do not treat it as a production deployment server. The Pyodide FAQ also notes that browser File System API support is not uniform across Firefox and Safari, so do not build a cross-browser workflow around that capability without checking current browser support.
Choose between Pyodide, PyScript, and Brython
These projects offer different ways to put Python in a browser. The available project descriptions do not establish that they have identical package compatibility or performance, so choose based on how you want to integrate Python and whether your dependencies are supported.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Rank #2
| Option | Integration style | Consider it when | Important qualification |
|---|---|---|---|
| Pyodide | Load a runtime from JavaScript and call Python explicitly with runPython(). |
You want direct control over when Python starts and how JavaScript invokes it. | Check package support and load additional packages as needed; standard-library packages are available immediately after import. |
| PyScript | An HTML-oriented browser application platform. | You prefer an HTML-facing approach rather than writing all runtime calls yourself. | The project description identifies Pyodide and MicroPython among its technologies. Consult its current documentation for the version’s syntax and supported features: PyScript project. |
| Brython | A Python 3 implementation for browsers with interfaces for DOM elements and events. | You want a browser-oriented Python interface to page elements and events. | Its documentation describes serving a local project over HTTP and loading standard-library modules. The cited file/HTTP documentation is for version 3.10: Brython file and HTTP documentation. |
Before committing to any option, check whether the libraries your application needs are available and how the chosen runtime exposes browser APIs. Do not assume a package built for desktop Python will work unchanged in a browser.
Load packages beyond the standard library
Pyodide’s quickstart says that only standard-library packages are available immediately after import. Additional packages need to be loaded using Pyodide’s package-loading approach, and the package and its dependencies must be supported in that environment. Consult the quickstart and the package guidance in the usage guide for the current method.
A dependency that installs successfully in a desktop virtual environment is not automatically usable in the browser. Check availability, dependencies, and any runtime limitations before designing around it. The Pyodide distribution path and its NPM mirror are also different: the guide distinguishes a distribution that includes packages from an NPM mirror containing only the runtime. Select the delivery route that matches the packages and build process you need.
Keep the page responsive during longer computations
By default, WebAssembly runs in the main browser thread, and long computations can make the interface unresponsive. Pyodide’s usage guide identifies a Web Worker as one solution. If the page performs substantial computation, move the work off the UI thread and communicate progress or results back to the page rather than making a long synchronous call from a click handler.
Free tools Windows power users keep installed
One-click scans. No signup required.
For short examples, direct calls are simpler. For a real application, account for startup time, the runtime and package downloads, and the duration of the Python task. Avoid starting the runtime repeatedly for each interaction; initialize once and reuse it while the page remains active. These are implementation considerations, not a published speed comparison between Pyodide, PyScript, and Brython.
Browser support and runtime delivery
The stable Pyodide guide recommends recent browsers and lists tested minimum versions of Firefox 112, Chrome 112, and Safari 16.4. Those are the versions listed by the documentation page, not a guarantee about every device or future browser release. Check the current guide and test the browsers your users actually use.
For deployed pages, use a versioned runtime URL and keep the runtime version controlled as part of your release. The development documentation warns against deploying from a development CDN URL. If you use an NPM-based workflow, note that the NPM mirror contains only the runtime while the distribution includes packages; verify which assets your application expects before switching delivery approaches.
Troubleshooting browser Python
The page says loadPyodide is not defined
- Check that the
pyodide.jsscript URL is valid and that the browser successfully downloaded it. - Ensure your initialization runs after the script is loaded. In the example, the runtime script appears before the inline code that calls
loadPyodide(). - Open the browser developer console and network panel to inspect script-loading errors, including blocked requests or an unavailable version path.
Python runs before initialization completes
loadPyodide() is asynchronous. Await it before calling runPython(), and keep controls disabled until it resolves. If initialization throws, display the error and provide a retry or reload path instead of calling methods on an unset runtime.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteAn import fails even though the package works on desktop
Pyodide starts with standard-library packages; additional packages must be loaded, and not every desktop dependency is necessarily supported in a browser runtime. Check the current package guidance and whether dependencies are available for the selected runtime rather than assuming a desktop installation transfers unchanged.
A local data file cannot be loaded from file:///
Use an HTTP development server, such as python -m http.server 8000, and open the page through http://localhost:8000/. Browser security restrictions prevent ordinary JavaScript from freely loading local data files through file URLs. File System API behavior also varies across browsers, including Firefox and Safari, as noted in the Pyodide FAQ.
The page freezes while Python is working
A long computation on the main browser thread can block interface updates. Move work to a Web Worker and report results or progress back to the page. If a worker is not appropriate, reduce the amount of work per interaction and avoid synchronous long-running tasks on the UI thread.
The page works in one browser but not another
Compare the browser with the minimum versions currently listed in the Pyodide guide, then test the actual target browsers. Differences in browser capabilities, runtime versions, file access, or package support can affect behavior; a successful run in one browser is not proof of identical support elsewhere.
Best Value
Or skip the browser setup
If your goal is to capture a website rather than execute Python in the page, ScreenshotNeo is a website screenshot API and MCP server: one GET request can return a PNG, JPEG, WebP, or PDF. Its clean-shot flow accepts consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing status.
Here is a cURL request:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Replace YOUR_API_KEY with your key and change the target URL as needed. See the ScreenshotNeo API documentation for the available options. ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.
Frequently Asked Questions
Can Python in a browser access the page’s DOM?
Yes, but the integration depends on the runtime. Pyodide is called from JavaScript, which can interact with the DOM; Brython’s project describes interfaces for DOM elements and events. Check the selected project’s current documentation for its supported API.
Does browser Python replace a Python server?
No. This approach runs Python in the visitor’s browser. It does not by itself provide server-side execution, shared data storage, or protected server credentials.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

