PyMarklet
Generate a browser bookmarklet that runs a Python script with Pyodide. The generated bookmarklet adds a draggable output panel to the current page, loads Python in WebAssembly, and runs your embedded script in the browser.
Experimental: PyMarklet executes code in the context of the web page where the bookmarklet is activated. Read the Security and privacy section before sharing or running a bookmarklet.
Installation
python -m pip install pymarklet
PyMarklet requires Python 3.11 or later to generate bookmarklets. The resulting bookmarklet runs Python in a supported modern browser; it does not use your local Python environment at runtime.
Quick start
Create a Python script:
# hello.py
print("Hello from Python in your browser!")
Generate a bookmarklet URL:
pymarklet hello.py -o hello-bookmarklet.txt
- Open
hello-bookmarklet.txtand copy its complete contents. - Create a browser bookmark named PyMarklet: hello.
- Paste the copied
javascript:URL into the bookmark's URL/location field. - Visit a webpage and activate the bookmark.
A panel appears in the upper-right corner with status and Python output. Drag its header to move it, click × to remove it, and click the canvas before sending keyboard input to graphical applications.
Some browsers block pasting
javascript:URLs into the address bar. Paste the URL into a bookmark's URL field instead.
Command line
pymarklet [-h] [-o OUTPUT] python_file
| Argument | Description |
|---|---|
python_file |
UTF-8 Python source file to embed. |
-o, --output |
Destination file for the bookmarklet URL. Defaults to bookmarklet.js in the current directory. |
The command returns a nonzero status if it cannot read the source or write the output file.
Dependencies
PyMarklet determines dependencies in two stages when the bookmarklet runs:
- It asks Pyodide to load packages it recognizes from normal
importstatements. - For missing imports, it attempts to install a package with the same name using
micropip.
When a PyPI distribution name differs from its import name, declare it in a first-line manifest:
# PKGS: python-dateutil, more-itertools
from dateutil import parser
from more_itertools import chunked
print(parser.isoparse("2026-10-10T12:34:56Z"))
print(list(chunked(range(6), 2)))
The manifest is comma-separated, case-insensitive (# pkgs: also works), trims duplicates, and accepts normal PyPI requirement specifiers such as requests>=2.32. Use it for every dependency whose import name is not its distribution name—for example, scikit-learn / sklearn.
How it works
The generated URL embeds your source, creates a small page overlay, and loads Pyodide 0.27.5 from jsDelivr. Standard output and errors appear in the overlay. The canvas is available to Pyodide-compatible graphical libraries such as Pygame.
The source in examples/integration_stress_test.py and the page in examples/sandbox.html are a manual integration example:
pymarklet examples/integration_stress_test.py
Open examples/sandbox.html in a browser, then use the generated bookmarklet on that page.
Limitations
- Network access is required. The browser fetches Pyodide from jsDelivr and may fetch packages from PyPI-compatible hosts.
- Content Security Policy (CSP) can prevent execution. Sites may block the injected Pyodide script, package downloads, or required browser APIs.
- Only Pyodide-compatible packages work. Native packages without compatible WebAssembly wheels cannot be installed.
- Import detection is static and best-effort. Dynamic imports and relative imports are not detected; use
# PKGS:for dependencies that need explicit installation. - Bookmark URLs have practical length limits. The loader is already several thousand characters long, and the URL grows with your script. Keep scripts small.
- Closing the overlay removes its UI but does not forcibly cancel Python work already scheduled in the page.
Security and privacy
- A bookmarklet is executable code. Only run bookmarklets you trust.
- Your Python source is embedded in the bookmarklet URL. Never include secrets, credentials, private endpoints, or sensitive data. Anyone with the URL can extract the source.
- The bookmarklet executes with the permissions and network environment of the page where you activate it. Review site policies and do not use it on pages where injected code is inappropriate.
- Dependencies are downloaded and executed in the browser. Pin or constrain declared requirements where reproducibility matters.
- PyMarklet relies on jsDelivr to serve its pinned Pyodide runtime. Ad blockers, offline mode, proxies, or supply-chain policy may block it.
See SECURITY.md for vulnerability reporting.
Development
uv sync
uv run python -m unittest discover -s tests -v
uv build
Contributions are welcome; see CONTRIBUTING.md. This project is licensed under the MIT License.
Publishing checklist
Before the first public release, confirm the pymarklet name is available on PyPI and configure PyPI Trusted Publishing for this repository and the pypi GitHub environment.
Metadata
Release files for pymarklet 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pymarklet-0.1.0.tar.gz | 8.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pymarklet-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.2 kB
Release files / pymarklet-0.1.0.tar.gz
| Download URL | pymarklet-0.1.0.tar.gz |
|---|---|
| Size | 8.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cdee8a70bdde1e87842fc9a341a9aed99aaf7d47a69548d0150cea7e6efc77dd
|
|
BLAKE2b-256 checksum How to use checksums |
053ee28b30fed57ca8651709c994f32129f0fc44c9aa8f5f022a78400efee6f2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logRelease files / pymarklet-0.1.0-py3-none-any.whl
| Download URL | pymarklet-0.1.0-py3-none-any.whl |
|---|---|
| Size | 9.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9f1f0d32647260e8a25d229b1389551bc030e783ea4a228b352eca7cadb29b87
|
|
BLAKE2b-256 checksum How to use checksums |
ed1b1d3e68651ef6964d77d83caf52b8e33611d1f1352d5c486e539c60d6af8a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency log