[{"data":1,"prerenderedAt":617},["ShallowReactive",2],{"navigation_docs":3,"-guide-benchmarks":223,"-guide-benchmarks-surround":612},[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":92,"body":225,"description":605,"extension":606,"links":607,"meta":608,"navigation":609,"path":93,"seo":610,"stem":94,"__hash__":611},"docs\u002F2.guide\u002F13.benchmarks.md",{"type":226,"value":227,"toc":600},"minimark",[228,245,249,254,267,296,303,307,310,576,579,596],[229,230,235],"pre",{"className":231,"code":232,"language":233,"meta":234,"style":234},"language-sh shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","sbt 'set core \u002F Test \u002F javaOptions += \"-Dtui4s.stress=30\"' 'core\u002FtestOnly tui4s.stress.PerfProbe'\n","sh","",[236,237,238],"code",{"__ignoreMap":234},[239,240,243],"span",{"class":241,"line":242},"line",1,[239,244,232],{},[246,247,248],"p",{},"This probe measures the pure layout and paint of one frame, with no runner and no terminal. It prints the median and the 90th percentile of each step, in ms, for a dashboard, a list of 2,000 rows and a log.",[250,251,253],"h2",{"id":252},"bench","bench\u002F",[246,255,256,257,259,260,263,264,266],{},"The ",[236,258,253],{}," directory compares the same apps in tui4s and in seven other terminal UI stacks (Java, Scala, Rust, Go, Python and Node.js). It has its own sbt build (",[236,261,262],{},"bench\u002Fbuild.sbt",") and its own CI job (",[236,265,252],{},"). The headline is not speed. It is:",[268,269,270,278,284,290],"ul",{},[271,272,273,277],"li",{},[274,275,276],"strong",{},"Compactness",": the size of the code of the same app.",[271,279,280,283],{},[274,281,282],{},"Expressiveness",": what each library can say directly.",[271,285,286,289],{},[274,287,288],{},"Correctness",": the same behaviour in each implementation.",[271,291,292,295],{},[274,293,294],{},"Resource management",": how each library releases the terminal and its other resources.",[246,297,298,299,302],{},"A person of each ecosystem has not reviewed the implementations of the other stacks yet. The numbers of stage 1 come from a shared build container (4 vCPU, noisy). The run on a bounded cloud machine that stops by itself (",[236,300,301],{},"bench\u002Finfra",") is written, but it has not run yet.",[250,304,306],{"id":305},"stage-1","Stage 1",[246,308,309],{},"Two tasks, a counter and a dashboard. \"lines\" is the source without blank lines and comments. \"key-script steps\" are the steps of the screen oracle of both tasks. \"restore cases\" are the six ways to end each task (quit, Ctrl-C, SIGTERM, SIGINT, a failure in a key handler, a kill during a frame) after which the terminal is restored. A mutant is a small bug in the counter (13 classes): \"found\" is the compiler, a crash or the oracle; \"defused\" has no effect; \"silent\" is wrong and passes; \"not run\" is not applicable or not written.",[311,312,313,351],"table",{},[314,315,316],"thead",{},[317,318,319,323,326,330,333,336,339,342,345,348],"tr",{},[320,321,322],"th",{},"Stack",[320,324,325],{},"Language",[320,327,329],{"align":328},"right","counter lines",[320,331,332],{"align":328},"dashboard lines",[320,334,335],{"align":328},"key-script steps",[320,337,338],{"align":328},"restore cases",[320,340,341],{"align":328},"mutants found",[320,343,344],{"align":328},"defused",[320,346,347],{"align":328},"silent",[320,349,350],{"align":328},"not run",[352,353,354,386,414,441,469,496,523,550],"tbody",{},[317,355,356,360,363,366,369,372,375,378,381,383],{},[357,358,359],"td",{},"tui4s",[357,361,362],{},"Scala",[357,364,365],{"align":328},"27",[357,367,368],{"align":328},"78",[357,370,371],{"align":328},"28\u002F28",[357,373,374],{"align":328},"12\u002F12",[357,376,377],{"align":328},"8",[357,379,380],{"align":328},"2",[357,382,380],{"align":328},[357,384,385],{"align":328},"1",[317,387,388,391,394,397,400,402,404,407,410,412],{},[357,389,390],{},"jatatui-plain",[357,392,393],{},"Java",[357,395,396],{"align":328},"70",[357,398,399],{"align":328},"154",[357,401,371],{"align":328},[357,403,374],{"align":328},[357,405,406],{"align":328},"13",[357,408,409],{"align":328},"0",[357,411,409],{"align":328},[357,413,409],{"align":328},[317,415,416,419,421,424,427,429,432,435,437,439],{},[357,417,418],{},"TamboUI",[357,420,393],{},[357,422,423],{"align":328},"46",[357,425,426],{"align":328},"120",[357,428,371],{"align":328},[357,430,431],{"align":328},"10\u002F12",[357,433,434],{"align":328},"11",[357,436,409],{"align":328},[357,438,385],{"align":328},[357,440,385],{"align":328},[317,442,443,446,448,451,454,457,459,462,464,466],{},[357,444,445],{},"layoutz",[357,447,362],{},[357,449,450],{"align":328},"23",[357,452,453],{"align":328},"83",[357,455,456],{"align":328},"22\u002F28",[357,458,374],{"align":328},[357,460,461],{"align":328},"5",[357,463,409],{"align":328},[357,465,380],{"align":328},[357,467,468],{"align":328},"6",[317,470,471,474,477,480,483,485,487,490,492,494],{},[357,472,473],{},"ratatui",[357,475,476],{},"Rust",[357,478,479],{"align":328},"53",[357,481,482],{"align":328},"138",[357,484,371],{"align":328},[357,486,374],{"align":328},[357,488,489],{"align":328},"12",[357,491,409],{"align":328},[357,493,385],{"align":328},[357,495,409],{"align":328},[317,497,498,501,504,507,510,512,514,517,519,521],{},[357,499,500],{},"bubbletea",[357,502,503],{},"Go",[357,505,506],{"align":328},"52",[357,508,509],{"align":328},"119",[357,511,371],{"align":328},[357,513,374],{"align":328},[357,515,516],{"align":328},"10",[357,518,409],{"align":328},[357,520,385],{"align":328},[357,522,380],{"align":328},[317,524,525,528,531,534,537,539,541,543,545,547],{},[357,526,527],{},"Textual",[357,529,530],{},"Python",[357,532,533],{"align":328},"37",[357,535,536],{"align":328},"102",[357,538,371],{"align":328},[357,540,374],{"align":328},[357,542,468],{"align":328},[357,544,380],{"align":328},[357,546,385],{"align":328},[357,548,549],{"align":328},"4",[317,551,552,555,558,561,564,566,568,570,572,574],{},[357,553,554],{},"ink",[357,556,557],{},"Node.js",[357,559,560],{"align":328},"28",[357,562,563],{"align":328},"103",[357,565,371],{"align":328},[357,567,374],{"align":328},[357,569,377],{"align":328},[357,571,409],{"align":328},[357,573,385],{"align":328},[357,575,549],{"align":328},[246,577,578],{},"layoutz never enters the alternate screen, and it fails the start, the modes and the resize steps. TamboUI shows an error screen after a failure in a key handler, and the next keys have no effect.",[246,580,581,582,589,590,595],{},"The full tables (tokens, gzip bytes, the concepts, the size of a change request, each restore case and each mutant) and the findings are in ",[583,584,588],"a",{"href":585,"rel":586},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fblob\u002Fmain\u002Fbench\u002FREADME.md",[587],"nofollow","bench\u002FREADME.md",". The start time, the memory, the CPU and the size of each stack are on ",[583,591,594],{"href":592,"rel":593},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fblob\u002Fmain\u002Fbench\u002FPERFORMANCE.md",[587],"bench\u002FPERFORMANCE.md",", with the machine and the method.",[597,598,599],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":234,"searchDepth":601,"depth":601,"links":602},2,[603,604],{"id":252,"depth":601,"text":253},{"id":305,"depth":601,"text":306},"The frame-path probe of tui4s, and the bench of tui4s against seven other terminal UI stacks.","md",null,{},{"icon":95},{"title":92,"description":605},"v8WlpVLOlaWc3q73ZNoZRDGp6KdHHBm2Klxx6QAS5tU",[613,615],{"title":87,"path":88,"stem":89,"description":614,"icon":90,"children":-1},"What the runner does to the terminal, and how each way that a run ends restores it.",{"title":97,"path":103,"stem":104,"description":616,"icon":98,"children":-1},"How an AI agent reads this documentation and works on the tui4s repository.",1792528755401]