[{"data":1,"prerenderedAt":438},["ShallowReactive",2],{"navigation_docs":3,"-decisions-0013-benchmarks-in-repo-with-own-build":223,"-decisions-0013-benchmarks-in-repo-with-own-build-surround":433},[4,26,96,105,202],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":25},"Getting started","i-lucide-rocket","\u002Fgetting-started","1.getting-started",[10,15,20],{"title":11,"path":12,"stem":13,"icon":14},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F1.installation","i-lucide-download",{"title":16,"path":17,"stem":18,"icon":19},"The first app","\u002Fgetting-started\u002Ffirst-app","1.getting-started\u002F2.first-app","i-lucide-play",{"title":21,"path":22,"stem":23,"icon":24},"The first test","\u002Fgetting-started\u002Ffirst-test","1.getting-started\u002F3.first-test","i-lucide-flask-conical",false,{"title":27,"icon":28,"path":29,"stem":30,"children":31,"page":25},"Guide","i-lucide-book-open","\u002Fguide","2.guide",[32,37,42,47,52,57,62,67,72,77,81,86,91],{"title":33,"path":34,"stem":35,"icon":36},"Components","\u002Fguide\u002Fcomponents","2.guide\u002F01.components","i-lucide-component",{"title":38,"path":39,"stem":40,"icon":41},"Inputs and forms","\u002Fguide\u002Finputs-and-forms","2.guide\u002F02.inputs-and-forms","i-lucide-text-cursor-input",{"title":43,"path":44,"stem":45,"icon":46},"Scrolling and viewports","\u002Fguide\u002Fscrolling","2.guide\u002F03.scrolling","i-lucide-scroll-text",{"title":48,"path":49,"stem":50,"icon":51},"Overlays and layers","\u002Fguide\u002Foverlays","2.guide\u002F04.overlays","i-lucide-layers",{"title":53,"path":54,"stem":55,"icon":56},"Styles and theme","\u002Fguide\u002Fstyles","2.guide\u002F05.styles","i-lucide-palette",{"title":58,"path":59,"stem":60,"icon":61},"Composables","\u002Fguide\u002Fcomposables","2.guide\u002F06.composables","i-lucide-puzzle",{"title":63,"path":64,"stem":65,"icon":66},"Widgets","\u002Fguide\u002Fwidgets","2.guide\u002F07.widgets","i-lucide-blocks",{"title":68,"path":69,"stem":70,"icon":71},"The assistant","\u002Fguide\u002Fassistant","2.guide\u002F08.assistant","i-lucide-message-square",{"title":73,"path":74,"stem":75,"icon":76},"The same app on the web","\u002Fguide\u002Fweb","2.guide\u002F09.web","i-lucide-globe",{"title":78,"path":79,"stem":80,"icon":24},"Testing","\u002Fguide\u002Ftesting","2.guide\u002F10.testing",{"title":82,"path":83,"stem":84,"icon":85},"Running and packaging","\u002Fguide\u002Fpackaging","2.guide\u002F11.packaging","i-lucide-package",{"title":87,"path":88,"stem":89,"icon":90},"The terminal contract","\u002Fguide\u002Fterminal","2.guide\u002F12.terminal","i-lucide-square-terminal",{"title":92,"path":93,"stem":94,"icon":95},"Benchmarks","\u002Fguide\u002Fbenchmarks","2.guide\u002F13.benchmarks","i-lucide-gauge",{"title":97,"icon":98,"path":99,"stem":100,"children":101,"page":25},"AI and agents","i-lucide-bot","\u002Fai","3.ai",[102],{"title":97,"path":103,"stem":104,"icon":98},"\u002Fai\u002Fagents","3.ai\u002F1.agents",{"title":106,"icon":107,"path":108,"stem":109,"children":110},"Decisions","i-lucide-scale","\u002Fdecisions","4.decisions",[111,114,118,122,126,130,134,138,142,146,150,154,158,162,166,170,174,178,182,186,190,194,198],{"title":112,"path":108,"stem":113,"icon":46},"All decisions","4.decisions\u002Findex",{"title":115,"path":116,"stem":117},"0001. kyo-ui is the DSL","\u002Fdecisions\u002F0001-kyo-ui-is-the-dsl","4.decisions\u002F0001-kyo-ui-is-the-dsl",{"title":119,"path":120,"stem":121},"0002. jatatui renders the cells","\u002Fdecisions\u002F0002-jatatui-renders-the-cells","4.decisions\u002F0002-jatatui-renders-the-cells",{"title":123,"path":124,"stem":125},"0003. Pin Kyo 1.0.0-RC7 and JDK 25","\u002Fdecisions\u002F0003-pin-kyo-rc7-and-jdk-25","4.decisions\u002F0003-pin-kyo-rc7-and-jdk-25",{"title":127,"path":128,"stem":129},"0004. Public Kyo APIs only","\u002Fdecisions\u002F0004-public-kyo-apis-only","4.decisions\u002F0004-public-kyo-apis-only",{"title":131,"path":132,"stem":133},"0005. A SOFT frame contract and an own watcher loop","\u002Fdecisions\u002F0005-soft-frame-contract-and-own-watcher-loop","4.decisions\u002F0005-soft-frame-contract-and-own-watcher-loop",{"title":135,"path":136,"stem":137},"0006. Purity: edge files, lint and a pure painter","\u002Fdecisions\u002F0006-purity-edge-files-and-lint","4.decisions\u002F0006-purity-edge-files-and-lint",{"title":139,"path":140,"stem":141},"0007. Compiler flags from sbt-tpolecat","\u002Fdecisions\u002F0007-compiler-flags-from-sbt-tpolecat","4.decisions\u002F0007-compiler-flags-from-sbt-tpolecat",{"title":143,"path":144,"stem":145},"0008. The artifact split: runner, app, testkit and core","\u002Fdecisions\u002F0008-artifact-split-runner-app-testkit-core","4.decisions\u002F0008-artifact-split-runner-app-testkit-core",{"title":147,"path":148,"stem":149},"0009. tui4s-use and tui4s-widgets, cross-built","\u002Fdecisions\u002F0009-use-and-widgets-cross-built","4.decisions\u002F0009-use-and-widgets-cross-built",{"title":151,"path":152,"stem":153},"0010. The flagship assistant is the blueprint of a real app","\u002Fdecisions\u002F0010-the-flagship-assistant-as-blueprint","4.decisions\u002F0010-the-flagship-assistant-as-blueprint",{"title":155,"path":156,"stem":157},"0011. The web target: a standalone Scala.js app and one theme","\u002Fdecisions\u002F0011-web-target-standalone-scalajs-and-one-theme","4.decisions\u002F0011-web-target-standalone-scalajs-and-one-theme",{"title":159,"path":160,"stem":161},"0012. The documentation is example-first","\u002Fdecisions\u002F0012-documentation-is-example-first","4.decisions\u002F0012-documentation-is-example-first",{"title":163,"path":164,"stem":165},"0013. Benchmarks in the repository, with their own build","\u002Fdecisions\u002F0013-benchmarks-in-repo-with-own-build","4.decisions\u002F0013-benchmarks-in-repo-with-own-build",{"title":167,"path":168,"stem":169},"0014. Release per module, by tag, as 0.1.0-RC1","\u002Fdecisions\u002F0014-release-per-module-tags-and-rc1","4.decisions\u002F0014-release-per-module-tags-and-rc1",{"title":171,"path":172,"stem":173},"0015. Packaging: the AOT cache in the start scripts, native-image as an option","\u002Fdecisions\u002F0015-packaging-aot-cache-and-native-image","4.decisions\u002F0015-packaging-aot-cache-and-native-image",{"title":175,"path":176,"stem":177},"0016. Process: lean mode and agent roles","\u002Fdecisions\u002F0016-process-lean-mode-and-agent-roles","4.decisions\u002F0016-process-lean-mode-and-agent-roles",{"title":179,"path":180,"stem":181},"0017. Deferred: templates, mouse, the kitty keyboard protocol and Windows","\u002Fdecisions\u002F0017-deferred-templates-mouse-and-kitty","4.decisions\u002F0017-deferred-templates-mouse-and-kitty",{"title":183,"path":184,"stem":185},"0018. pini4s is a vendored Git submodule","\u002Fdecisions\u002F0018-pini4s-as-a-vendored-submodule","4.decisions\u002F0018-pini4s-as-a-vendored-submodule",{"title":187,"path":188,"stem":189},"0019. Upstream issues are drafts that the user posts","\u002Fdecisions\u002F0019-upstream-kyo-issues-as-drafts","4.decisions\u002F0019-upstream-kyo-issues-as-drafts",{"title":191,"path":192,"stem":193},"0020. Release from the Actions form","\u002Fdecisions\u002F0020-release-from-the-actions-form","4.decisions\u002F0020-release-from-the-actions-form",{"title":195,"path":196,"stem":197},"0021. The rulebook is CONTRIBUTING.md","\u002Fdecisions\u002F0021-the-rulebook-is-contributing-md","4.decisions\u002F0021-the-rulebook-is-contributing-md",{"title":199,"path":200,"stem":201},"0022. The logo is text","\u002Fdecisions\u002F0022-the-logo-is-text","4.decisions\u002F0022-the-logo-is-text",{"title":203,"icon":204,"path":205,"stem":206,"children":207,"page":25},"Project","i-lucide-compass","\u002Fproject","5.project",[208,213,218],{"title":209,"path":210,"stem":211,"icon":212},"Roadmap","\u002Fproject\u002Froadmap","5.project\u002F1.roadmap","i-lucide-map",{"title":214,"path":215,"stem":216,"icon":217},"Contributing","\u002Fproject\u002Fcontributing","5.project\u002F2.contributing","i-lucide-git-pull-request",{"title":219,"path":220,"stem":221,"icon":222},"Security","\u002Fproject\u002Fsecurity","5.project\u002F3.security","i-lucide-shield",{"id":224,"title":163,"body":225,"description":426,"extension":427,"links":428,"meta":429,"navigation":430,"path":164,"seo":431,"stem":165,"__hash__":432},"docs\u002F4.decisions\u002F0013-benchmarks-in-repo-with-own-build.md",{"type":226,"value":227,"toc":415},"minimark",[228,233,251,255,258,262,297,301,344,348,379,383,403,407],[229,230,232],"h2",{"id":231},"status","Status",[234,235,236,237,244,245,250],"p",{},"Accepted. Stage 1 landed on 2026-10-20 (L5): two tasks in eight stacks, with the mutant suite; the TamboUI mutants came in L6. The run on a dedicated machine is ",[238,239,243],"a",{"href":240,"rel":241},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fissues\u002F51",[242],"nofollow","#51",", and the review by a person of each ecosystem is ",[238,246,249],{"href":247,"rel":248},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fissues\u002F34",[242],"#34",".",[229,252,254],{"id":253},"date","Date",[234,256,257],{},"2026-10-17 (D10 as changed by the user); 2026-10-19 (the machine).",[229,259,261],{"id":260},"context","Context",[263,264,265,269,272,279,291,294],"ul",{},[266,267,268],"li",{},"The user asked for benchmarks \"against Scala and other languages, and a comparison of expressiveness and correctness\".",[266,270,271],{},"Research of 2026-10-17: tui4s will very likely lose on startup, memory, size and idle CPU. It can win on bug classes caught at compile time, cleanup guarantees (scoped fibers, terminal restore) and code size.",[266,273,274,275,278],{},"A JVM peer and a plain jatatui program split the cost: the JVM floor, then Scala and Kyo, then kyo-ui and tui4s. A plain Java jatatui counter starts in 147 ms against 1,101 ms for the tui4s launcher (",[238,276,277],{"href":172},"ADR 0015",").",[266,280,281,282,286,287,290],{},"A change in the root ",[283,284,285],"code",{},"build.sbt"," or in ",[283,288,289],{},"project\u002F"," marks every published module unreleased.",[266,292,293],{},"CI runners are noisy. Headline numbers need a dedicated machine.",[266,295,296],{},"Competitor code written by people outside an ecosystem can be unidiomatic (vendor bias).",[229,298,300],{"id":299},"decision","Decision",[263,302,303,321,324,327,330,341],{},[266,304,305,306,309,310,313,314,317,318,278],{},"The benchmarks live in ",[283,307,308],{},"bench\u002F"," with their own sbt build, outside the root build. They use the ",[283,311,312],{},"publishLocal"," artifacts. Other languages go in ",[283,315,316],{},"bench\u002Fimpl\u002F\u003Clanguage>\u002F",". They have their own CI job (",[283,319,320],{},"bench.yml",[266,322,323],{},"The tasks are rosetta tasks with one JSON acceptance scenario each. Stage 1 is Counter (T1) and Dashboard (T4) in tui4s, plain jatatui, ratatui, Bubble Tea, Textual, Ink, TamboUI (a JVM peer) and layoutz.",[266,325,326],{},"The headline axes are compactness, expressiveness, correctness and resource management. A mutant suite (13 bug classes) and a resilience suite (signals, crash restore) measure correctness.",[266,328,329],{},"Performance is published honestly on its own page (\"where tui4s loses\"), with the same charts as the wins.",[266,331,332,333,336,337,340],{},"The machine is the user's AWS account, set up with alchemy from ",[283,334,335],{},"bench\u002Finfra\u002F",": one bounded instance, no inbound ports, IMDSv2, ",[283,338,339],{},"shutdown -h +90",", terminate on shutdown, results to S3.",[266,342,343],{},"Results are published after 0.1.",[229,345,347],{"id":346},"alternatives-considered","Alternatives considered",[263,349,350,361,367,373],{},[266,351,352,356,357,360],{},[353,354,355],"strong",{},"A separate repository"," (for example ",[283,358,359],{},"yuri4n\u002Ftui4s-bench","), easier for competitor maintainers to send pull requests to. Not chosen: the user put it in this repository. The reason is not recorded.",[266,362,363,366],{},[353,364,365],{},"Performance as the headline."," Rejected: tui4s loses on it; the headline is what it can win, and performance gets its own honest page.",[266,368,369,372],{},[353,370,371],{},"No dedicated machine (container or CI numbers only)."," Rejected for headline numbers: CI runners are noisy. The user gave the AWS account (D10, 2026-10-19).",[266,374,375,378],{},[353,376,377],{},"The benchmarks inside the root build."," Rejected: a bench change would mark every published module unreleased.",[229,380,382],{"id":381},"consequences","Consequences",[263,384,385,388,391,394,400],{},[266,386,387],{},"Good: no published module becomes unreleased because of a bench change.",[266,389,390],{},"Good: the comparison is reproducible from the repository, with Nix for the toolchains.",[266,392,393],{},"Bad: several languages and toolchains to maintain; the competitor set may be too large for a lean program.",[266,395,396,397,278],{},"Bad: competitor implementations need a review by a person of each ecosystem before the results are published (",[238,398,249],{"href":247,"rel":399},[242],[266,401,402],{},"Bad: the AWS run costs money and needs credentials; it must stay bounded and auto-terminate.",[229,404,406],{"id":405},"references","References",[263,408,409,412],{},[266,410,411],{},"Roadmap: 2.6 (benchmarks), 2.7 (startup numbers), D10. Decision log: fifteenth round, sixteenth round (D10 machine).",[266,413,414],{},"Handoff: \"L5 LAUNCHED 2026-10-20\".",{"title":416,"searchDepth":417,"depth":417,"links":418},"",2,[419,420,421,422,423,424,425],{"id":231,"depth":417,"text":232},{"id":253,"depth":417,"text":254},{"id":260,"depth":417,"text":261},{"id":299,"depth":417,"text":300},{"id":346,"depth":417,"text":347},{"id":381,"depth":417,"text":382},{"id":405,"depth":417,"text":406},"The comparison lives in bench\u002F with its own sbt build and other languages in bench\u002Fimpl\u002F\u003Clanguage>; its headline is compactness, expressiveness, correctness and resource management, and performance is published honestly on its own page.","md",null,{},true,{"title":163,"description":426},"w_VbAKweJAEPOUXya4e0Eo1xVcZ1yfPIqMt3i2Z26Uw",[434,436],{"title":159,"path":160,"stem":161,"description":435,"children":-1},"Every public API ships with a compiled example; README and docs code blocks are regions of tested files; the docs site is Nuxt Docus on Vercel; work lands on one branch with CI on demand.",{"title":167,"path":168,"stem":169,"description":437,"children":-1},"Each module has its own version and tag; the first release is 0.1.0-RC1 while Kyo is an RC; a human approves every tag; the empty zio and cats modules and the deprecated useSignal go before 0.1.",1792528756973]