kiwisolver

Fast Python bindings to Kiwi, a C++ implementation of the Cassowary constraint-solving algorithm used to lay out matplotlib figures and Qt UIs

Library
PyPI
v1.5.0
780stars
Custom / Unknown

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
66/100Good
Development Activity60
Maintenance40
Community76
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
76/100Good
Architecture85
Code Quality80
Innovation78
Learning Curve60

kiwisolver is the Python binding to Kiwi, an efficient C++ implementation of the Cassowary linear-arithmetic constraint-solving algorithm. Rather than a refactor of the original academic Cassowary solver, Kiwi was rewritten from scratch for speed and low memory use, reporting 10x-500x throughput improvements and more than 5x lower memory usage than the reference implementation.

kiwisolver lets you declare a system of linear equality/inequality constraints over named variables (e.g. x + y == 10) and have the solver compute a consistent assignment, with support for incremental constraint editing so a UI or plot layout can be re-solved cheaply as it changes. It is best known as the constraint-solving engine behind matplotlib’s layout system and is also used by the Enaml/Qt-based atom/enaml UI toolkits from the same nucleic organization.

What You Get

  • A Solver class for adding/removing linear constraints (Constraint, built from Variable/Expression arithmetic) and computing consistent variable values
  • Support for required and optional (strength-weighted) constraints, so a layout can prefer certain arrangements while still satisfying hard requirements
  • Efficient incremental re-solving: editing a subset of constraints or variable values doesn’t require rebuilding the whole constraint system from scratch
  • A compiled C++ extension (via the kiwi C++ library) for solver performance, with a typed Python API (py.typed) on top
  • Cross-platform prebuilt wheels published for CPython across major OSes, making installation dependency-free for most users

Common Use Cases

  • Powering matplotlib’s constraint-based layout engine, which arranges subplots, axes, and figure elements automatically
  • Building constraint-based UI layout systems, similar to Apple’s Auto Layout or Cassowary-based toolkits, for Python GUI frameworks (as done by Enaml/Atom)
  • Any application needing to solve a system of linear equality/inequality constraints efficiently and incrementally, outside of pure layout use cases
  • Replacing ad-hoc layout math with a declarative constraint model that’s solved once and re-solved cheaply on changes

Under The Hood

Architecture - The C++ core (kiwi/) implements the dual-simplex-based Cassowary algorithm (solver.h/solverimpl.h), maintaining an internal tableau of rows/symbols and applying incremental updates rather than re-solving from scratch on each edit, which is the source of its large performance advantage over the reference Cassowary implementation; the Python layer (py/src/*.cpp) is a hand-written CPython C-extension (kiwisolver.cpp, variable.cpp, constraint.cpp) that wraps the C++ Solver/Variable/Constraint types directly rather than going through a generic binding generator like pybind11 or SWIG. Tech Stack - The solver core is header-only modern C++ (kiwi/*.h) built via CMake, and the Python package builds this into a CPython extension module using setuptools/pyproject.toml-based packaging with prebuilt wheels distributed for common platforms. Code Quality - The repository has separate C++ tests (tests/SimplexTest.cpp, tests/SolverTest.cpp) and Python tests (py/tests/), plus CI running continuous integration and codecov coverage tracking across both layers, indicating dual-layer test discipline for the native and binding code paths. API Design - The Python API models constraint arithmetic idiomatically: Variable instances support normal Python operators (+, -, *, ==, <=, >=) to build Expression and Constraint objects, so solver.addConstraint(x + y == 10) reads as ordinary algebra rather than a solver-specific DSL, keeping the barrier to embedding it in a layout engine low.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search