{"slug": "airunner-is-becoming-a-set-of-tools-instead-of-one-giant-tree", "title": "AIRunner is becoming a set of tools instead of one giant tree", "summary": "A developer split the open-source desktop AI application AIRunner into four independently publishable packages: airunner-eval, airunner-tts-vendor, airunner-native and airunner-common. The refactor also moved the web engine's world and economy layer into uwuchat-worldsystems, renamed the service package to airunner_engine, and relocated shared LLMRequest and LLMResponse payloads into airunner-common, with import boundaries enforced in CI. The developer advises extraction only when a package has its own reason to change, its own tests and a public consumer that should not install the rest of the application.", "body_md": "I had let [AIRunner](https://github.com/Capsize-Games/airunner), my open-source desktop AI application, do too much in one repository. The split is now visible in four public packages: [airunner-eval](https://github.com/Capsize-Games/airunner-eval), [airunner-tts-vendor](https://github.com/Capsize-Games/airunner-tts-vendor), [airunner-native](https://github.com/Capsize-Games/airunner-native) and [airunner-common](https://github.com/Capsize-Games/airunner-common).\n\nThe names describe the boundaries. The evaluation package can process models without dragging the application into the run. The TTS vendor fork can be tested and published without importing the host application's database. Native tools can stay close to their sidecar binaries. Shared request and response payloads can be versioned once and consumed by the desktop and service layers.\n\nThe web engine moved in the same direction. It stopped naming the products it hosts, moved the world and economy layer into `uwuchat-worldsystems`, and renamed the service package to `airunner_engine`. The remaining boundary is visible in the code instead of being a convention in a README. That matters when a new application is added because the engine has fewer reasons to know it exists.\n\nThe stack is still familiar: Python, PySide6, HTTP and WebSocket services, package publishing and CI checks. The work was less about picking a new framework and more about making the existing contracts explicit. Import boundaries run in CI. The desktop/daemon contract has a version. Shared `LLMRequest` and `LLMResponse` payloads live in `airunner-common` instead of being copied between packages.\n\nThe user-facing site is [airunner.art](https://airunner.art/). The [four-week release overview](https://capsize.online/devlog/2026/09/20/four-weeks-of-building-in-public/) covers the other projects that moved alongside it.\n\nThe payoff is visible when a new change arrives. A model-evaluation change can stay in the evaluator. A native sidecar change can stay with the sidecar. The desktop app can consume a versioned payload instead of reaching into a folder that happened to be next door. Those are small boundaries, but they remove a lot of guesswork from the next release.\n\nExtraction is worth doing when the package has its own reason to change, its own tests and a public consumer that should not install the rest of the application. If those things are not true, a new repository is just another place to forget to update.\n\nThe next AIRunner step is to keep the service boundary just as clear as the first four extractions. The goal is a smaller set of packages that can be installed and released independently while the desktop application still feels like one thing.", "url": "https://wpnews.pro/news/airunner-is-becoming-a-set-of-tools-instead-of-one-giant-tree", "canonical_source": "https://dev.to/w4ffl35/airunner-is-becoming-a-set-of-tools-instead-of-one-giant-tree-3k9b", "published_at": "2026-09-24 15:15:01+00:00", "updated_at": "2026-09-24 15:29:55.281593+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "ai-infrastructure", "mlops"], "entities": ["AIRunner", "Capsize Games", "airunner-eval", "airunner-tts-vendor", "airunner-native", "airunner-common", "uwuchat-worldsystems", "PySide6"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/airunner-is-becoming-a-set-of-tools-instead-of-one-giant-tree", "markdown": "https://wpnews.pro/news/airunner-is-becoming-a-set-of-tools-instead-of-one-giant-tree.md", "text": "https://wpnews.pro/news/airunner-is-becoming-a-set-of-tools-instead-of-one-giant-tree.txt", "jsonld": "https://wpnews.pro/news/airunner-is-becoming-a-set-of-tools-instead-of-one-giant-tree.jsonld"}}