Run Python in Your Browser with PyScript

Discover how to bring Python's power to web frontends using WebAssembly. From data visualization to interactive dashboards, PyScript opens new possibilities for Python developers building modern web applications.

What is PyScript?

PyScript is an open-source framework created by Anaconda that enables Python code execution within modern web browsers. It builds upon Pyodide, a WebAssembly port of CPython, to bring the full Python runtime to the browser environment. According to InfoWorld's comprehensive overview, this technology enables Python developers to leverage their existing skills for frontend development.

The framework allows developers to embed Python code directly in HTML using custom tags or script elements, with full access to Python's standard library and many popular packages like NumPy, Pandas, and Matplotlib. What distinguishes PyScript from earlier attempts to run Python in browsers is its deep integration with browser APIs and JavaScript, enabling two-way communication between Python and the web page. The official PyScript documentation provides detailed guidance on this architecture.

How PyScript Works

At its core, PyScript leverages WebAssembly (WASM), a binary instruction format that runs at near-native speed in modern browsers. When a page containing PyScript loads, the browser downloads the Pyodide runtime, which includes the Python interpreter compiled to WebAssembly along with necessary JavaScript glue code. This one-time download enables subsequent Python code execution without server roundtrips. As explained in FullStack's technical guide, this architecture enables sophisticated applications while maintaining performance.

The architecture involves several layers working together: the browser's WebAssembly runtime, the Pyodide project providing Python-in-WebAssembly, and PyScript's own abstractions that simplify common tasks like DOM manipulation and package management.

Current Status and Production Readiness

Anaconda, the primary maintainer of PyScript, describes the project as experimental and does not recommend it for production use. The framework is actively developed with regular releases, and production deployments are possible with careful consideration of its limitations. Teams should evaluate whether PyScript's benefits outweigh its current constraints for their specific use cases. Our web development services team can help assess whether PyScript is appropriate for your project.

Setting Up PyScript in Your HTML

Getting started with PyScript requires adding the framework's CSS and JavaScript files to your HTML document. The official documentation recommends using specific version URLs rather than the "latest" endpoint to ensure stability and prevent breaking changes from affecting your application.

Basic HTML Structure

The minimal PyScript setup includes a link to the CSS file and a script tag loading the JavaScript runtime. Place these in the document's head to ensure proper initialization before your Python code executes:

<!DOCTYPE html>
<html>
<head>
 <link rel="stylesheet" href="https://pyscript.net/releases/2024.2.1/core.css">
 <script type="module" src="https://pyscript.net/releases/2024.2.1/core.js"></script>
</head>
<body>
 <!-- Your PyScript content goes here -->
</body>
</html>

The CSS file provides default styling for PyScript's built-in components and loading indicators, while the JavaScript module bootstraps the Pyodide runtime and sets up the infrastructure for Python execution.

Choosing Your Script Tag Approach

PyScript supports multiple ways to include Python code in HTML pages. The modern and recommended approach uses <script type="py"> tags, which align with the HTML standard's pattern for executable code.

For inline Python code, use the script tag with the type attribute set to "py":

<script type="py">
 from pyscript import display
 display("Hello from Python in the browser!")
</script>

For external Python files, reference them using the src attribute:

<script type="py" src="main.py"></script>

Configuration and Package Management

PyScript uses configuration files to specify packages, environment settings, and other options. Declare packages using the pyscript.toml file:

packages = ["numpy", "pandas", "matplotlib"]

Not all Python packages are compatible with PyScript. Pure Python packages from PyPI generally work, while packages with C extensions or platform-specific dependencies may fail. The PyScript documentation maintains a list of known compatible packages, and testing individual packages is recommended before relying on them. For complex web applications, consider our front-end development services to ensure proper architecture decisions.

Key PyScript Capabilities

Understanding the core features that make PyScript powerful

Standard Library Access

Use Python's extensive standard library including json, re, datetime, and more without additional configuration.

Third-Party Packages

Install and use popular packages like NumPy, Pandas, and Matplotlib directly in the browser.

JavaScript Interop

Bridge Python and JavaScript seamlessly, accessing browser APIs and JavaScript libraries from Python.

DOM Manipulation

Find, create, and modify HTML elements using Python code with familiar DOM methods.

Web Workers

Run Python in background threads to keep your UI responsive during heavy computations.

Interactive Terminal

Enable Python REPL functionality in the browser for interactive applications.

Interacting with JavaScript

One of PyScript's most powerful features is its ability to bridge Python and JavaScript, allowing developers to leverage both ecosystems within a single application. This interoperability enables sophisticated hybrid applications where Python handles computational tasks and JavaScript manages UI rendering.

Accessing JavaScript Objects

The js module provides access to browser globals and JavaScript objects. Access window properties, DOM elements, and JavaScript functions directly:

from js import window, document, console

# Access browser APIs
width = window.innerWidth
height = window.innerHeight
print(f"Browser size: {width}x{height}")

# Log to console
console.log("Hello from Python!")

# Access DOM elements
element = document.getElementById("my-element")

Importing JavaScript Libraries

JavaScript libraries can be imported alongside Python code. Include the library's JavaScript file in your HTML, then import its functions in Python:

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
from js import Chart, document

# Create a chart using the Chart.js library
ctx = document.getElementById("chart-canvas")
chart = Chart.new(ctx, {
 "type": "bar",
 "data": {
 "labels": ["January", "February", "March"],
 "datasets": [{
 "label": "Sales",
 "data": [65, 59, 80]
 }]
 }
})

This pattern enables using mature JavaScript ecosystems like charting libraries, animation frameworks, and UI components while writing application logic in Python. The approach documented by FullStack demonstrates effective patterns for this hybrid development.

DOM Manipulation with Python

Manipulating web page elements directly from Python code is a core PyScript capability, enabling dynamic content updates and user interaction handling. This bridges the gap between Python's familiar syntax and web development's document-centric model.

Finding and Modifying Elements

The document object from the js module provides familiar DOM methods:

from js import document

# Find elements
header = document.getElementById("main-header")
paragraphs = document.querySelectorAll("p.content")

# Modify content
header.textContent = "Updated Header"
header.classList.add("highlighted")

# Create new elements
new_div = document.createElement("div")
new_div.textContent = "Created from Python!"
new_div.className = "python-created"
document.body.appendChild(new_div)

Event Handling

Register event handlers to respond to user interactions:

from js import document
from pyodide.ffi import create_proxy

def on_button_click(event):
 print(f"Button clicked at {event.timeStamp}")

# Create proxy for proper lifecycle management
click_proxy = create_proxy(on_button_click)
button = document.getElementById("submit-button")
button.addEventListener("click", click_proxy)

Remember to remove event listeners when they're no longer needed to prevent memory leaks, especially in single-page applications. For more complex frontend interactions, consider our React development services which offer mature solutions for dynamic user interfaces.

Performance Considerations

Understanding PyScript's performance characteristics helps set appropriate expectations and optimize applications effectively. The technology offers unique capabilities but comes with specific trade-offs that developers must consider.

Initial Load Time

The primary performance consideration is initial load time. When a user first visits a page with PyScript, the browser must download the Pyodide runtime (approximately 10MB compressed), which can take several seconds depending on network speed. Subsequent page visits benefit from browser caching, reducing load time to the size of your Python code only. As detailed in FullStack's optimization guide, strategies to minimize impact include lazy loading and proper caching strategies.

Strategies to minimize the impact of initial load include:

  • Show loading indicators to provide feedback during initialization
  • Consider preloading PyScript on landing pages for subsequent page loads
  • Use lazy loading to defer PyScript initialization until content is needed
  • Optimize code size through code splitting and lazy imports

Execution Performance

Once loaded, Python execution in PyScript performs reasonably for compute-intensive tasks, though generally slower than native JavaScript. The WebAssembly runtime executes at near-native speed for pure Python code, but operations involving heavy JavaScript interop incur conversion overhead.

For best execution performance:

  • Minimize roundtrips between Python and JavaScript by batching operations
  • Use NumPy and other compiled packages for numerical operations
  • Run long-running computations in web workers to avoid blocking the UI

Web Workers for Background Processing

The worker attribute runs Python code in a separate thread, preventing CPU-intensive tasks from freezing the user interface:

<script type="py" worker src="heavy_computation.py"></script>

Worker mode enables interactive applications that perform complex calculations, data processing, or machine learning inference without sacrificing UI responsiveness.

Best Practices for PyScript Development

Following established practices helps create maintainable, performant PyScript applications. These guidelines reflect lessons learned from real-world deployments and community experience.

Development Workflow

Use the PyScript VS Code extension during development. It provides syntax highlighting for Python in HTML files, code snippets for common PyScript patterns, and better integration with Python's language server. These tools catch errors early and improve development velocity. As recommended in FullStack's development guide, proper tooling significantly improves productivity.

Structure projects with separate Python files rather than inline code when possible. This enables proper version control diffs, code reuse across pages, and better tooling support. Use configuration files to declare dependencies clearly.

Code Organization

Organize PyScript projects with clear separation of concerns:

project/
├── index.html
├── pyscript.toml
├── css/
│ └── styles.css
├── python/
│ ├── main.py
│ ├── utils.py
│ └── components/
│ ├── charts.py
│ └── forms.py
└── js/
 └── vendor/
 └── chart.min.js

Separate Python and JavaScript folders make the codebase easier to navigate, especially in larger projects where multiple team members may work on different aspects.

Error Handling and Debugging

Implement robust error handling since PyScript errors may not be as visible as JavaScript errors:

try:
 result = risky_operation()
 display(f"Success: {result}")
except Exception as e:
 error_div = document.getElementById("error-display")
 error_div.textContent = f"Error: {str(e)}"
 error_div.classList.add("visible")

Use print statements and browser developer tools to debug PyScript code. The terminal output mode provides real-time feedback during development.

Data Visualization

Create interactive charts and dashboards using Matplotlib, Plotly, or D3.js through Python. Leverage Python's data science ecosystem to build compelling visualizations that run entirely in the browser.

Scientific Computing

Run NumPy, SciPy, and Pandas computations client-side without server roundtrips. Process data locally and deliver real-time insights to users without backend dependencies.

Machine Learning

Deploy pre-trained models for inference directly in the user's browser. Build intelligent applications that make predictions without sending data to external servers.

Education

Teach Python programming in browser-based environments with immediate feedback. Create interactive coding exercises that run without local Python installations.

Ready to Modernize Your Web Development?

Our team specializes in cutting-edge web technologies including WebAssembly, Python integrations, and modern frontend frameworks. Let us help you build powerful web applications that leverage the best tools for your needs.

Frequently Asked Questions

Sources

  1. InfoWorld - Intro to PyScript - Comprehensive technical overview covering PyScript basics and architecture
  2. PyScript Documentation - First Steps - Official guidance on getting started with PyScript
  3. FullStack - PyScript Best Practices - Developer-focused best practices and optimization strategies
  4. PyScript Official Website - Main landing page with current release information
  5. PyScript GitHub Repository - Official code repository with examples and community resources