Skip to main content

Pysual

Python interfaces for Window, Terminal, and Web.

Assign controls, change their properties, and name event handlers. The same application runs in a native window, a terminal, or an SVG browser interface. Python 3.11+. MIT licensed. Early development; APIs may change.

See the 0.1.3 release notes for fixes and supported scope.

Install

A published release installs with pip. Python 3.11 or newer:

python -m pip install pysual

Windows x64, Linux x64, and Apple Silicon wheels include the native window host and the SDL libraries it needs. Other platforms receive the pure-Python wheel, whose Python terminal and web backends are ready to use. Building a window host for another platform is described in building.

Start in a browser

git clone https://github.com/PabloMP2P/Pysual.git
cd Pysual
python -m venv .venv
# Activate .venv using your shell, then:
python -m pip install -e '.[dev,build]'
python examples/hello.py --backend web

Activate with .venv\Scripts\Activate.ps1 in PowerShell or source .venv/bin/activate on macOS/Linux. The live Web host and Python terminal renderer need no graphics packages or C compiler. For library-only installation, use python -m pip install ..

python examples/hello.py --backend terminal --terminal python
python -m pysual native
python examples/hello.py --backend window

The native builder finds a C compiler and provisions checksum-pinned SDL development packages on Windows. Linux/macOS require a C11 compiler, pkg-config, SDL3, SDL3_ttf, and SDL3_image development libraries. See building for compiler and platform details.

Write an application

from pysual import App, Button, Label

class Hello(App):
    def build(self):
        self.title = "Hello"
        self.layout, self.padding, self.spacing = "stack", 24, 12
        self.message = Label(text="Ready")
        self.greet = Button(text="Say hello")

    def greet_on_click(self, event):
        self.message.text = "Hello, Pysual!"

Hello().run_blocking(backend="web")

Assignment adopts and names each control; greet_on_click binds automatically. Names must not collide with existing members: the factory names label, button, image, slider, menu and the other snake-case control names are taken, so prefer descriptive names such as message or save_button (a BindingError names the conflict). Handlers can be synchronous or async def. Properties and public methods route to the UI owner automatically. run() returns after the first frame for REPLs and scripts doing other work; wait() waits for closure. run_blocking() combines the two. Import pysual.autoconfig before creating controls to enable --backend, --terminal, --pysual-theme, and --pysual-scale in your own script.

Three backends

Backend Runtime Distribution
window Standalone C renderer with SDL3, text, images, effects, retained scenes, and native animations Executable for the build machine's OS and architecture
terminal C character renderer; auto, c, or python renderer selection Executable, including a Python-only option requiring no C build
web SVG with local Python when served; Python in Pyodide when bundled One HTML file embedding the application, fonts, and runtime

Terminal auto prefers an available C host and falls back to Python when it cannot start. Choose --terminal c to require C, or --terminal python for a dependency-free renderer. Terminal typography follows the emulator's cell grid.

python -m pysual examples/hello.py --backend window -o dist/hello.exe
python -m pysual examples/hello.py --backend terminal --terminal python -o dist/hello-terminal.exe
python -m pysual examples/hello.py --backend web -o dist/hello.html

Use extensionless executable names on Linux/macOS. Build on each target OS; these commands do not cross-compile. Outside a checkout the same commands are pysual build … (or python -m pysual build …) after pip install. Web builds fetch a checksum-pinned Pyodide runtime once; --runtime PATH makes subsequent builds fully local. Serve the bundled HTML from a static HTTP host. Application handlers remain Python and need no application Python server. See Web delivery.

Included

  • 43 catalog controls: editable grids, virtual lists/trees, tabs, menus, dialogs, text and value editors, charts, range selection, navigation, choice cards, disclosure groups, badges, actionable alerts, meters, and progress.
  • Five layout modes, nine theme families in light and dark (18 themes), 44 icons, bundled fonts, shadows, gradients, surfaces, interaction motion, and custom painting.
  • Unicode text editing, selection, clipboard where supported, undo/redo, async events, drag/drop, and batched property updates.
  • Retained rendering, bounded caches, on-demand frames, and incremental native scene updates.
Example What it demonstrates
hello.py Automatic binding, text input, async events
dashboard.py Editable data, filtering, charts
showcase.py Controls, themes, layout, effects
theme_gallery.py An interactive control studio with all nine theme families, light/dark switching, and desktop-inspired materials
stress_test.py Configurable control mixes, workloads, timing, and JSON reports
custom_control.py Observable properties and portable drawing
composite_control.py Reusable compound controls with independent child state and handlers
catalog_controls.py Thirteen catalog ideas in a responsive review workspace with collapsible filters, review plans, status feedback, and live theme switching

Choose Modern, Windows, macOS, Terminal, Win31, WinXP, Macintosh, Analog arcade, or Neon. Each has a light and dark version with its own control surfaces, typography, borders, and interaction states. Preview them with:

python examples/theme_gallery.py --backend web

See the rendered comparison of all 18 appearances.

Use get_theme("winxp") for light and get_theme("winxp_dark") for dark. See themes and custom painting for the complete catalog and compatibility details.

Stress test

The stress lab mixes 20 control types, including grids, trees, charts, images, and editors. Choose balanced, text, forms, visual, or collections scenes, with presets from 100 to 5,000 controls or an exact count up to 20,000. It opens on the large preset with continuous redraw and VSync off.

python examples/stress_test.py --backend window --controls 2000 --mix balanced --workload local-update
python examples/stress_test.py --backend terminal --terminal python --controls 100 --mix forms
python examples/stress_test.py --backend web --mix visual
python examples/stress_test.py --controls 500 --workload property --fraction 0.25 --rate 60 --warmup 2 --duration 10 --report work/stress.json

Changing a preset or another dashboard control applies it immediately. Pause, restart measurements, or export a JSON report from the same bar. --help lists the control mixes and rendering options. Timed runs measure --duration seconds after warmup. Use the same seed, viewport, theme, workload, and rendering settings when comparing runs.

Workloads cover idle scenes, paint invalidation, layout changes, property updates, and one-control updates. Rendering options include the presentation cap, redraw interval, VSync, body reuse, and surface-cache budget.

Python submission rates, native presentation loops, and terminal output counters are reported separately. These do not measure physical screen refresh or browser paint. Live metrics refresh at 4 Hz by default and add work to a static scene; pass --no-telemetry to leave them on demand. Collection rows and chart points are counted separately from widgets.

Develop

Style and commit conventions are in Contributing.

python -m pytest
python tools/check_typing.py

After changing control properties, run python tools/generate_factory_types.py to refresh the factory typing signatures. Add --check to verify them without writing changes; the generator needs only the Python standard library.

For new controls, see control composition and catalog development.

The full test suite requires Node.js 24 for the Web JavaScript contracts. Native tests require a built host and report explicit skips otherwise. CI builds and checks the native implementation separately. Applications need no Node.js or npm project.

API guide · Native rendering · Building · Web · Contributing

Controls are custom drawn. OS accessibility bridges, complex-script shaping, full font fallback, mobile hosts, and OS-level modality between separate native processes are outside this release's supported scope. Real display, terminal, clipboard, IME, and packaged-app behavior should be checked on the target system.

Metadata

Release files for pysual 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pysual 0.1.3
File Size Uploaded Provenance
pysual-0.1.3.tar.gz 3.5 MB With provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for pysual 0.1.3
File
pysual-0.1.3-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
pysual-0.1.3-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl Python 3 none Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
pysual-0.1.3-py3-none-macosx_26_0_arm64.whl Python 3 none macOS 26.0+ ARM64 Details
pysual-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 16.4 MB

Release files / pysual-0.1.3.tar.gz

Download URL pysual-0.1.3.tar.gz
Size 3.5 MB
Tags Source
SHA-256 checksum
How to use checksums
b17fb453b4257297b4c218b6e2785fbaf0626d19280b182048c37fb066cb53c3
BLAKE2b-256 checksum
How to use checksums
fd6a18fc228767e4cf6ff78d4be751f4eac9fc893f4b400479bc8423d651bda1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 21, 2026.

Transparency log

Release files / pysual-0.1.3-py3-none-win_amd64.whl

Download URL pysual-0.1.3-py3-none-win_amd64.whl
Size 3.6 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
ec2f6f28fb1838f0c0acbb283f10f1537743519281f7905d7015583f5f491027
BLAKE2b-256 checksum
How to use checksums
a4a663ce7c33c42dea8e7b1ae7256ca8e6e718aaa689b4e5e3e3b745e586e30c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 21, 2026.

Transparency log

Release files / pysual-0.1.3-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL pysual-0.1.3-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 4.2 MB
Tags Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 Python 3
SHA-256 checksum
How to use checksums
63b3e2ca515acf81cb5faa1de208529f01770e88df2bda31be2fbf38e1e19213
BLAKE2b-256 checksum
How to use checksums
0f449262a5fff06758d9f91a56791a554578cb86f3077f30ba7c8ebaf2b4bb7b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 21, 2026.

Transparency log

Release files / pysual-0.1.3-py3-none-macosx_26_0_arm64.whl

Download URL pysual-0.1.3-py3-none-macosx_26_0_arm64.whl
Size 4.1 MB
Tags Python 3 macOS 26.0+ ARM64
SHA-256 checksum
How to use checksums
ecaa6574920ef5aebc6f3999877403652ba8b38709221e92fdc58684ea133823
BLAKE2b-256 checksum
How to use checksums
aae67d18cb35cedc9cb3d23a7e5fc109ffa37deaf32212c27b0623dd101e8d64
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 21, 2026.

Transparency log

Release files / pysual-0.1.3-py3-none-any.whl

Download URL pysual-0.1.3-py3-none-any.whl
Size 1.1 MB
Tags Python 3
SHA-256 checksum
How to use checksums
2f5dbed55d1c25230e381ce9f9b0221ed90a3a9c52370b9b684b9a885778cb3b
BLAKE2b-256 checksum
How to use checksums
aea8f49623ccfdc4d69e399ac9cae31703ade76c7f8ba2587546743cd191a13a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 21, 2026.

Transparency log

Security for pysual 0.1.3

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.

Full provenance

All 5 files in this release have been uploaded with provenance metadata.

Select from 5 files

Attestation for pysual-0.1.3.tar.gz

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 21, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page