Stretchable

raw JSON →
1.1.8 verified Sat May 09 auth: no python

A Python layout library that uses Taffy, a Rust-powered implementation of CSS Grid and Flexbox, to compute layouts declaratively. Current version is 1.1.8, supporting Python >=3.8. Release cadence is irregular, approximately bi-monthly.

pip install stretchable
error TypeError: 'int' object is not callable
cause Mistaking Auto for a function; Auto is a constant sentinel, not a callable.
fix
Use Auto directly: size={'width': Auto, 'height': 100}.
error AttributeError: 'NoneType' object has no attribute 'left'
cause Calling tree.get_layout() for a node that hasn't been added to the tree or layout not computed.
fix
Ensure node is added as child via root.add_child(node) and call tree.compute_layout() before get_layout().
error ModuleNotFoundError: No module named 'stretchable'
cause stretchable not installed or installed in a different environment.
fix
Run 'pip install stretchable'. If using virtual environments, ensure it is activated.
gotcha Nodes must be added as children before calling tree.compute_layout(), otherwise they are not part of the layout calculation.
fix Call root.add_child(child) before tree.compute_layout().
breaking Upgrade to v1.1.0 introduced breaking changes due to Taffy 0.5.1 upgrade. CSS Block layout and overflow support were added; some APIs changed (e.g., measure function signatures).
fix Refer to migration notes in GitHub releases. For custom measure functions, ensure they match the new signature (width, height, available_width, available_height).
gotcha The size property in Style expects a dictionary, not a tuple. Common mistake: using size=(100, 50) instead of size={"width": 100, "height": 50}.
fix Use dictionary format: size={'width': 100, 'height': 50}.
deprecated Direct assignment to Node.style (e.g., node.style = new_style) is deprecated after v1.1.1. Use setter method or property assignment carefully.
fix Use node.style_setter() or modify individual properties of node.style (e.g., node.style.flex_direction = 'row').

Quickstart: create nodes, add children, compute layout, and access results.

from stretchable import Node, LayoutTree, Style

# Create a root node with flexbox layout
root = Node(style=Style(size={"width": 100, "height": 100}, display="flex", flex_direction="column", gap=10))
child1 = Node(style=Style(size={"width": 50, "height": 30}))
child2 = Node(style=Style(size={"width": 50, "height": 30}))

# Build and compute layout
tree = LayoutTree(root)
root.add_child(child1)
root.add_child(child2)
tree.compute_layout()

# Print layout of child1
layout = tree.get_layout(child1)
print(f"Child1: left={layout.left}, top={layout.top}, width={layout.width}, height={layout.height}")