Skip to content

Tesserae Engine

A GPU-rendered retained-mode UI engine for Python, written in Rust.

Tesserae Engine (imported as tre) gives Python the building blocks of a desktop UI — nodes, layout, paint, animation, input, text, accessibility, and layers — and renders them on the GPU. It has no widgets and no theme of its own: a UI library or application built on it turns the blocks into buttons, dialogs, and design systems. You write Python; the engine underneath uses:

from tre import App, Window

window = Window(width=320, height=120, title="Hello")
button = window.create("box", width=120, height=40, corner_radius=20,
                       fill=(0x67, 0x50, 0xA4, 0xFF), role="button",
                       label="Say hello", focusable=True)
button.on("click", lambda: print("hello"))
window.root.add_child(button)

app = App()
app.add_window(window)
app.run()

The building blocks

  • Nodes and layout — boxes, text, text inputs, images, paths, canvases, scroll views (scrolled by wheel, keys, and focus, with a scroll event), virtual lists, and terminals, laid out with flexbox or CSS Grid or placed absolutely.
  • Painting — fills, strokes, per-corner radii, layered shadows, group opacity, transforms, and SVG paths, redrawing only what changed each frame.
  • Animation — any paint or transform property, eased on a cubic-bezier curve, retargetable mid-flight, with path morphing.
  • Events and input — bubbling listeners, pointer capture, the mouse's back and forward buttons, keyboard focus, text editing, and the clipboard.
  • Text — shaped text, measurement, custom fonts, text inputs, and a terminal emulator.
  • Accessibility — roles, names, states, and actions for screen readers.
  • Layers — one mechanism for menus, dialogs, and tooltips: stacking, anchoring, modality, and dismissal.
  • Threading — hand work from any thread to the event loop.
  • Docking — panels in zones, dragged between them.
  • Custom Title Bars — an undecorated window with a title bar, buttons, and borders of your own (0.5.0).
  • Shaders — your own WGSL paints a node or transforms its rendered content (0.5.1).

Building a Widget puts them together into a complete switch.

What Tesserae Engine leaves to your code

  • Widgets and design — any design system is built from the blocks; Tesserae Engine draws no default styling, focus ring, or scrim.
  • Declarative views and state — views, bindings, and reactivity sit on top of window.create, node.set, and insert_child.
  • Files — images arrive as decoded pixels and fonts as bytes; Tesserae Engine reads no files and chooses no formats. This includes the pictures inside an SVG document: a framework decodes them and hands over the pixels (see SVG documents).

Where to go next

  • Installation — pip install tesserae-engine, a released wheel, or a build from source.
  • Getting Started — a first window, step by step.
  • Python API and Rust API — every class or type with its properties, methods and events, on one page each, for quick reference. The Reference pages go deeper.
  • Upgrading to 0.5.x — from 0.4.x: no renames, custom windowing, and a window root's fill now paints.
  • Upgrading to 0.4.x — from 0.3.5: no renames, a few behavior changes.
  • Upgrading to 0.3.5 — from 0.3.4: what left the engine and what was renamed.
  • Architecture — the crates and how a frame is made.

Tesserae Engine is a second, from-scratch iteration of an earlier Vulkan engine, archived under archive/ with the lessons learned that shaped it. Its build history is in the GitHub project Tesserae Rendering Engine (0.5.0 on), BUILD_TRACKER_ARCHIVE_0.4.md (0.4.x), and BUILD_TRACKER_ARCHIVE_0.3.md (through 0.3.5).