Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
loadPyodide
✓ import { loadPyodide } from 'pyodide';
// Or for older Node.js/CJS:
// const { loadPyodide } = require('pyodide');
✗ import loadPyodide from 'pyodide'; // Not a default export
The primary asynchronous function to initialize the Pyodide runtime. It returns a `PyodideInterface` instance. Pyodide officially supports ESM.
PyodideInterface
✓ import type { PyodideInterface } from 'pyodide';
TypeScript type for the object returned by `loadPyodide`, providing access to Python execution and utilities.
pyodide.runPython
✓ await pyodide.runPython(`
import sys
print('Hello from Python!', file=sys.stderr)
`);
✗ pyodide.runPython('print("Hello")'); // Missing await, as it returns a Promise
Executes Python code as a string. Must be `await`ed as it returns a Promise. Standard output and error can be redirected via `pyodide.setStdout` and `pyodide.setStderr` for custom handling.
pyodide.loadPackage
✓ await pyodide.loadPackage('numpy');
✗ pyodide.loadPackage('pandas'); // Missing await
Loads pre-compiled Pyodide packages from a CDN. Returns a Promise. For pure Python packages, `micropip.install` is generally preferred for dependency resolution.
micropip.install
✓ await pyodide.loadPackage('micropip');
const micropip = pyodide.pyimport('micropip');
await micropip.install('matplotlib');
✗ await pyodide.install('requests'); // No direct 'install' method on pyodide object
Used for installing Python packages, especially pure Python wheels, from PyPI within the Pyodide environment. `micropip` itself must first be loaded as a package.
This quickstart demonstrates how to load Pyodide, execute basic Python code, install a scientific package like NumPy, and facilitate data exchange between JavaScript and Python, all within a browser environment.
import { loadPyodide } from 'pyodide';
async function main() {
console.log('Initializing Pyodide...');
const pyodide = await loadPyodide({
indexURL: 'https://cdn.jsdelivr.net/pyodide/v0.25.0/full/' // Always pin the version!
});
console.log('Pyodide initialized.');
// Redirect Python stdout/stderr to JS console
pyodide.setStdout((text) => console.log('PY_STDOUT:', text));
pyodide.setStderr((text) => console.error('PY_STDERR:', text));
// Run simple Python code
console.log('Running Python code...');
const pythonResult = await pyodide.runPython(`
import sys
print('Hello from Python!')
x = 10
y = 20
x + y
`);
console.log('Python computed:', pythonResult);
// Load a Python package and use it
console.log('Loading NumPy...');
await pyodide.loadPackage('numpy');
const numpyVersion = pyodide.runPython('import numpy; numpy.__version__');
console.log('NumPy version:', numpyVersion);
const jsArray = [1, 2, 3, 4, 5];
pyodide.globals.set('js_array', jsArray);
const pythonArrayResult = await pyodide.runPython(`
import numpy as np
py_array = np.array(js_array)
print(f'Python array sum: {py_array.sum()}')
py_array.tolist()
`);
console.log('Python processed array:', pythonArrayResult);
// Clean up PyProxy objects if necessary (important for preventing memory leaks)
pyodide.destroy();
console.log('Pyodide instance destroyed.');
}
main().catch(err => {
console.error('An error occurred:', err);
});
Debug
Known issues
breakingPyodide versions 0.x have undergone significant API redesigns, particularly around 0.17.0, which introduced a more robust `asyncio` integration and overhauled core APIs. Older code relying on pre-0.17 APIs will likely break.fixRefer to the official Pyodide documentation for the specific version you are upgrading to and update API calls accordingly, focusing on `loadPyodide`, `runPython`, and `pyodide.FS`.
affects: <0.17.0
gotchaPyodide bundles a full CPython interpreter and many scientific libraries, leading to a large initial download size (hundreds of MB for full distribution). This can severely impact page load performance.fixOptimize loading by using the minimal `pyodide-core` package where possible, preloading only essential packages, and deferring heavier libraries (e.g., scikit-learn) until needed. Utilize service workers and IndexedDB for caching to improve subsequent load times.
affects: >=0.1.0
gotchaLong-running Python computations executed directly on the main thread can block the browser's UI, leading to unresponsiveness.fixAlways run Pyodide within a Web Worker. Use `pyodide.runPythonAsync` for asynchronous Python code and design Python functions to be non-blocking where possible. Pass UI updates back via postMessage.
affects: >=0.1.0
gotchaWhen transferring Python objects to JavaScript, Pyodide creates `PyProxy` objects. Failing to explicitly call `.destroy()` on these proxies (especially for frequently created or large objects) can lead to memory leaks over time.fixEnsure that all `PyProxy` objects created on the JavaScript side are explicitly destroyed using `pyProxy.destroy()` when they are no longer needed. For simple data, use `toJs()` with `dict_converter` to convert Python objects to plain JavaScript structures.
affects: >=0.1.0
gotchaCalling `loadPyodide()` again after a previous attempt failed (e.g., due to a network error) will often throw an `Error: Pyodide is already loading` or similar, preventing retry logic.fixHandle `loadPyodide` failures by refreshing the worker or page. The Pyodide team suggests internal retry logic for network requests as a potential future improvement, but currently, clean recovery is difficult without a full reset.
affects: >=0.1.0
breakingPyodide is expected to transition to a new versioning scheme, potentially aligning with Python minor versions (e.g., 3.14.x) instead of the current 0.x series. This will be accompanied by a new ABI, which means packages built for older Pyodide ABIs will not be compatible with new major Pyodide versions.fixMonitor official announcements for the new versioning scheme and ABI changes. Be prepared to rebuild or update Python packages for new major Pyodide releases. Pin Pyodide versions to avoid unexpected breaking changes.
affects: >=0.x, upcoming 3.x
Errors
Common errors & fixes
Uncaught (in promise) Error: Pyodide is already loading
Attempting to call `loadPyodide` multiple times, especially after a prior load failed or is still in progress, without proper cleanup.
fixEnsure `loadPyodide` is only called once per worker or page lifecycle. If a load fails, a full page/worker reload might be necessary, as internal state is not easily reset. Implement retry logic around the entire worker initialization if network stability is a concern.
Module not found: Can't resolve 'fs/promises'
This error typically occurs when bundling Pyodide for a browser environment using tools like Webpack or Vite, as Pyodide's internal Node.js compatibility shims (which use `fs/promises`) are not correctly polyfilled or excluded for the browser target.
fixConfigure your bundler to correctly polyfill Node.js modules for browser environments. For Webpack, this might involve `resolve.fallback`. Ensure `pyodide` is treated as an external module or that its Node.js-specific parts are properly handled if you are only targeting the browser. In some cases, updating your bundler configuration or Pyodide version can resolve this.
ModuleNotFoundError: No module named 'pyodide'
This error occurs when trying to `pip install pyodide` in a native Python environment. The `pyodide` npm package is a JavaScript distribution, not a Python package intended for native Python installation. The Python module `pyodide` (and `piplite`) is only available within the Pyodide runtime or the `pyodide-py` package for type-checking.
fixTo use Pyodide, load it via JavaScript in a browser or Node.js environment. Do not try to `pip install pyodide`. If you need the Python `pyodide` module's API for type hints in a native Python project, install `pyodide-py` via `pip install pyodide-py`. When running within Pyodide, the `pyodide` module is available by default, and other packages are installed using `micropip.install`.
TypeError: object of type 'XXX' is not JSON serializable (from Python code)
Attempting to return complex Python objects (like NumPy arrays, Pandas DataFrames, or custom Python classes) directly to JavaScript, which expects JSON-serializable types or primitive values. JavaScript does not automatically know how to serialize arbitrary Python objects.
fixConvert Python objects to JavaScript-compatible types before returning them. For NumPy arrays, use `tolist()` (`py_array.tolist()`). For Pandas DataFrames, use `to_json()` or `to_dict()` (`df.to_json()`). For custom objects, provide a `__js_repr__` method or manually convert to basic Python types (lists, dicts) before converting to JS using `pyodide.toJs(python_object)`.
Audit
Dependencies
No dependency data recorded yet.