ultralight-py DOCSshabbywu/ultralight-py
DOCUMENTATION / GETTING-STARTEDView source on GitHub ↗

Getting started#

Install ultralight-py to create a native window, or execute scripts and capture pixels in an offscreen page.

Installation#

Requires Python 3.10+. Release wheels bundle Ultralight libraries and runtime resources; no separate SDK installation is needed.

python -m pip install ultralight-py

CI targets Windows x64, Linux x64 (glibc ≥ 2.34), and macOS ARM64 (11.3+). Available platforms depend on the release files. For source installation, see the Development guide.

Optional image dependencies:

python -m pip install 'ultralight-py[pillow,numpy]'

Creating a native window#

Save this code as hello.py and run python hello.py. API installs registered functions before the first page script; Application handles the window and event loop.

from ultralight_py import API, Application

with API("app") as api, Application() as app:

    @api.register
    def hello(name):
        return f"Hello, {name}!"

    window = app.create_window(800, 520, title="Hello, ultralight-py")
    api.attach(window.view)
    window.view.load_html("""
        <style>
          body { background: #111315; color: #edb584;
                 font: 24px system-ui; padding: 48px; }
        </style>
        <h1 id="hello"></h1>
        <script>
          document.querySelector('#hello').textContent = app.hello('world');
        </script>
    """)
    app.run()

Create Application before the first Runtime. Engine operations run on Python's main thread, and the engine cannot be recreated in the current process after shutdown. AppCore handles system fonts, IME, and DPI. See Native windows and the API registry.

Offscreen rendering#

Without a window, use Runtime to create a CPU offscreen View. Standalone scripts can explicitly select ScriptDriver.auto() to advance loading/rendering while waiting.

import asyncio
from ultralight_py import Runtime
from ultralight_py.scripting import ScriptDriver


async def capture(runtime):
    with runtime.create_view(320, 180) as view:
        async with ScriptDriver.auto(runtime) as driver:
            await driver.page(view).load_html(
                "<style>body{background:#ff0000}</style><body>Hello",
                wait_until="settled",
                timeout=5,
            )
        print(view.evaluate("document.body.textContent"))
        frame = view.copy_pixels()
        print(frame.width, frame.height, frame.format)


with Runtime() as runtime:
    asyncio.run(capture(runtime))

Pixels use premultiplied-alpha BGRA8. frame.to_rgba() returns an independent RGBA image. For Pillow, NumPy, and row strides, see Pixels. Passive waits such as View.wait_ready() do not advance the engine themselves; an existing GUI loop must drive it.

Next steps#

Goal Read
Find methods, parameters, and return values Public API
Create windows, register functions, or use asyncio Native windows and API registry
Share Python/JavaScript objects bidirectionally Object bridging
Customize resources or handle events/input User guide
Explore complete applications, recordings, and source ultralight-py Showcase

Search docs

Enter a keyword to search APIs and guides

    ↑ ↓ Select · Enter Open · Esc Close