[{"data":1,"prerenderedAt":510},["ShallowReactive",2],{"navigation_docs":3,"-getting-started-installation":223,"-getting-started-installation-surround":507},[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":11,"body":225,"description":500,"extension":501,"links":502,"meta":503,"navigation":504,"path":12,"seo":505,"stem":13,"__hash__":506},"docs\u002F1.getting-started\u002F1.installation.md",{"type":226,"value":227,"toc":495},"minimark",[228,246,250,261,358,375,385,401,414,419,450,458,462,465,469,491],[229,230,236],"pre",{"className":231,"code":232,"filename":233,"language":234,"meta":235,"style":235},"language-sbt shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","libraryDependencies += \"io.github.yuri4n\" %% \"tui4s-core\" % \"\u003Cversion>\"\n","build.sbt","sbt","",[237,238,239],"code",{"__ignoreMap":235},[240,241,244],"span",{"class":242,"line":243},"line",1,[240,245,232],{},[247,248,249],"warning",{},"tui4s is under construction. No version is published yet.",[251,252,253,256,257,260],"p",{},[237,254,255],{},"tui4s-core"," gives the runner, ",[237,258,259],{},"TuiApp"," and the headless test kit in one dependency. Each artifact has its own version.",[262,263,264,277],"table",{},[265,266,267],"thead",{},[268,269,270,274],"tr",{},[271,272,273],"th",{},"Artifact",[271,275,276],{},"For",[278,279,280,291,313,325,338,348],"tbody",{},[268,281,282,288],{},[283,284,285],"td",{},[237,286,287],{},"io.github.yuri4n::tui4s-core",[283,289,290],{},"An app: tui4s-runner, tui4s-app and tui4s-testkit in one dependency.",[268,292,293,298],{},[283,294,295],{},[237,296,297],{},"io.github.yuri4n::tui4s-runner",[283,299,300,301,304,305,308,309,312],{},"The terminal runner for kyo-ui: ",[237,302,303],{},"Tui.run",", the components (",[237,306,307],{},"Hooks",", ",[237,310,311],{},"Component","), the screen types.",[268,314,315,320],{},[283,316,317],{},[237,318,319],{},"io.github.yuri4n::tui4s-app",[283,321,322,324],{},[237,323,259],{},", the main class of an app.",[268,326,327,332],{},[283,328,329],{},[237,330,331],{},"io.github.yuri4n::tui4s-testkit",[283,333,334,337],{},[237,335,336],{},"tui4s.testkit.Headless",", the headless test kit.",[268,339,340,345],{},[283,341,342],{},[237,343,344],{},"io.github.yuri4n::tui4s-use",[283,346,347],{},"Composables over Kyo signals, for the JVM and Scala.js.",[268,349,350,355],{},[283,351,352],{},[237,353,354],{},"io.github.yuri4n::tui4s-widgets",[283,356,357],{},"Widgets for the JVM and Scala.js, on tui4s-use.",[251,359,360,361,368,369,374],{},"There is no ZIO or Cats Effect module. Issues ",[362,363,367],"a",{"href":364,"rel":365},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fissues\u002F18",[366],"nofollow","#18"," and ",[362,370,373],{"href":371,"rel":372},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fissues\u002F19",[366],"#19"," track them.",[251,376,377,378,380,381,384],{},"A library, or a main of its own with no ",[237,379,259],{},", can use the runner alone. Then add the test kit in the ",[237,382,383],{},"Test"," scope:",[229,386,388],{"className":231,"code":387,"filename":233,"language":234,"meta":235,"style":235},"libraryDependencies += \"io.github.yuri4n\" %% \"tui4s-runner\"  % \"\u003Cversion>\"\nlibraryDependencies += \"io.github.yuri4n\" %% \"tui4s-testkit\" % \"\u003Cversion>\" % Test\n",[237,389,390,395],{"__ignoreMap":235},[240,391,392],{"class":242,"line":243},[240,393,394],{},"libraryDependencies += \"io.github.yuri4n\" %% \"tui4s-runner\"  % \"\u003Cversion>\"\n",[240,396,398],{"class":242,"line":397},2,[240,399,400],{},"libraryDependencies += \"io.github.yuri4n\" %% \"tui4s-testkit\" % \"\u003Cversion>\" % Test\n",[251,402,403,404,308,407,308,410,413],{},"tui4s-core, tui4s-runner, tui4s-app and tui4s-testkit use the same packages (",[237,405,406],{},"tui4s",[237,408,409],{},"tui4s.spi",[237,411,412],{},"tui4s.testkit","), so the imports do not change.",[415,416,418],"h2",{"id":417},"requirements","Requirements",[420,421,422,434,440],"ul",{},[423,424,425,429,430,433],"li",{},[426,427,428],"strong",{},"JDK 25."," Kyo 1.0.0-RC7 needs JDK 25 to compile and to run. Make sure that ",[237,431,432],{},"java -version"," shows 25.",[423,435,436,439],{},[426,437,438],{},"Scala 3.9.0"," or later.",[423,441,442,445,446,449],{},[426,443,444],{},"A deep compiler stack."," Kyo's inline for-comprehensions need it. Put this line in the ",[237,447,448],{},".jvmopts"," file at the root of the build:",[229,451,456],{"className":452,"code":454,"language":455,"meta":235},[453],"language-text","-Xss16m\n","text",[237,457,454],{"__ignoreMap":235},[415,459,461],{"id":460},"platforms","Platforms",[251,463,464],{},"CI checks the real terminal path on Linux, with a pseudo-terminal (the PTY kit). CI does not check other platforms. Windows is experimental. tui4s reads the keyboard, a paste and a resize. It does not read the mouse.",[415,466,468],{"id":467},"versions","Versions",[251,470,471,472,475,476,479,480,483,484,479,487,490],{},"Each module has its own version and its own release tag (",[237,473,474],{},"\u003Cmodule>-v\u003Cversion>","). The versions follow early semantic versioning: ",[237,477,478],{},"0.y.z"," to ",[237,481,482],{},"0.y.(z+1)"," is binary compatible, and ",[237,485,486],{},"0.y",[237,488,489],{},"0.(y+1)"," can break binary compatibility.",[492,493,494],"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":235,"searchDepth":397,"depth":397,"links":496},[497,498,499],{"id":417,"depth":397,"text":418},{"id":460,"depth":397,"text":461},{"id":467,"depth":397,"text":468},"Add tui4s to an sbt build, with JDK 25 and Scala 3.9.0.","md",null,{},{"icon":14},{"title":11,"description":500},"vWEBdbo_2-iDy7EMYgJx5guZrUjCv7CPuBBnpVX-ZdQ",[502,508],{"title":16,"path":17,"stem":18,"description":509,"icon":19,"children":-1},"The Counter example, its main class and its start script.",1792528752826]