Agent skill

Yoga Go Desktop UI

by chapar-rest in chapar-rest/chapar

Guides building desktop interfaces with the Yoga Go framework: Body views, layout nodes, widgets, dialogs and headless builds.

BSD-3-ClauseAuto-check passedDevelopment

Install Yoga Go Desktop UI

skills CLI
$ npx skills add chapar-rest/chapar --skill yoga-ui -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install chapar-rest/chapar yoga-ui --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/chapar-rest/chapar.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.cursor/skills/yoga-ui .claude/skills/yoga-ui && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
yoga-ui
GitHub stars
714
Token cost
~2.8k tokens
SKILL.md length
1,005 words
Files
3
Skills in repo
1
Repo updated
First seen
Licence
BSD-3-Clause

At a glance

Guides building desktop interfaces with the Yoga Go framework: Body views, layout nodes, widgets, dialogs and headless builds.

  • Works in 5 steps: App struct holds durable state (lists,… → Body(c) runs on every drawn wake and… → ui.View is Layout(c *ui.Ctx)… → …
  • Writing or changing a Yoga desktop app
  • SKILL.md covers Mental model, Bootstrap, Layout DSL (*ui.Node) and Controlled widgets, plus 6 more sections
  • Calls go

What it does

The skill explains Yoga's mental model: app state is kept between frames and the interface is rebuilt declaratively each frame, much like SwiftUI state. The app struct holds durable data, and Body runs on every drawn wake and returns a ui.View tree, while the GPU loop skips presenting when nothing visual changed. Widget micro-state such as hover, caret and scroll lives under c.Widget with a window-unique id, and a Ctx pointer must not be kept across frames, except the dialog, file, toast, focus and invalidate services, which are safe to capture in click handlers. Async work has to call Invalidate.

Heavy widgets (Editor, Table, Tree, FileTree, ListView) are built once in a Build function and placed with ui.ViewOf, while stateless nodes such as Column, Button and TextField can be created inside Body. yoga.Run creates the window and text engine and then calls build, so anything that measures text belongs inside build. The skill also covers the GPU entry point and the headless nogpu entry point, optional Close and OnKey hooks, and a layout table for Column, Row, Stack, Center and Spacer. Companion files widgets.md and examples.md list constructors and demo patterns.

When your agent uses it

  • Writing or changing a Yoga desktop app
  • Adding a widget such as a table, tree or editor
  • Showing dialogs, toasts or file pickers from a click handler
  • Setting up a headless nogpu build of an example

Example prompts

  • “Add a Table widget to the example app and fill it from the app's state.”
  • “Show a confirmation dialog from the Delete button's click handler.”
  • “Write the headless nogpu main for this demo.”

Requirements

  • A Go toolchain
  • The Yoga module github.com/mirzakhany/yoga

Workflow steps

5 steps, taken from the first numbered list in SKILL.md.

  1. App struct holds durable state (lists, strings, *ui.Editor, *ui.Table).
  2. Body(c) runs on every drawn wake and returns a ui.View tree. The GPU loop skips present (and the second Body rebuild) when nothing visual…
  3. ui.View is Layout(c *ui.Ctx) *layout.Element. *ui.Node implements it.
  4. Widget micro-state (hover, caret, scroll, open menu) lives in c.Widget(id, alloc) keyed by a unique-per-window id. App data does not.
  5. Do not retain per-frame *ui.Ctx fields across frames. The Ctx pointer is window-lifetime: c.Dialogs(), c.Files(), c.Toasts(), c.Focus()…

What it can do on your machine

Read from SKILL.md and the folder at commit 5a27fd5. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • go

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Yoga Go Desktop UI loads about 2.8k tokens when it runs. Until then it costs about 68 tokens; SKILL.md has 1,005 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~68
When it runs · the whole SKILL.md, loaded when a task matches
~2.8k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from chapar-rest/chapar at commit 5a27fd5, republished under its BSD-3-Clause licence (© chapar-rest). 1,005 words, ~2,805 tokens.

Download SKILL.mdSave it as .claude/skills/yoga-ui/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.
name
yoga-ui
description
Build desktop UI with the Yoga Go framework (github.com/mirzakhany/yoga): yoga.App, ui.View, Column/Row, widgets, theme tokens, overlays, focus. Use when writing or changing Yoga apps, widgets, example/* demos, or anything that implements Body(c *ui.Ctx) ui.View.

Yoga UI — agent instructions

Module github.com/mirzakhany/yoga. Public UI surface is ui/. Read widgets.md for constructors and examples.md for example/ patterns.

Mental model

Retained app state + per-frame declarative rebuild (SwiftUI @State analogue):

  1. App struct holds durable state (lists, strings, *ui.Editor, *ui.Table).
  2. Body(c) runs on every drawn wake and returns a ui.View tree. The GPU loop skips present (and the second Body rebuild) when nothing visual changed; idle WaitEvents does no work. There is no host widget cache / React reconciliation.
  3. ui.View is Layout(c *ui.Ctx) *layout.Element. *ui.Node implements it.
  4. Widget micro-state (hover, caret, scroll, open menu) lives in c.Widget(id, alloc) keyed by a unique-per-window id. App data does not.
  5. Do not retain per-frame *ui.Ctx fields across frames. The Ctx pointer is window-lifetime: c.Dialogs(), c.Files(), c.Toasts(), c.Focus(), c.Invalidate(), and c.MarkNeedsPaint() are safe to capture in OnClick. Async work must Invalidate() so the next wake paints.

Heavy widgets (Editor, Table, Tree, FileTree, ListView) are constructed once in Build* and placed with ui.ViewOf(w). Stateless DSL nodes (Column, Button, TextField, …) may be allocated in Body. Dialogs, file picker, and toasts are window services on c — do not construct or thread hosts.

Bootstrap

yoga.Run creates the window/text engine then calls build. Construct widgets that measure text inside build, never before Run.

go
package main

import (
	"github.com/mirzakhany/yoga"
	"github.com/mirzakhany/yoga/ui"
)

type App struct{ name string }

func Build() *App { return &App{} }

func (a *App) Body(c *ui.Ctx) ui.View {
	th := c.Theme()
	return ui.Column(
		ui.Title("Hello"),
		ui.TextField("name", a.name).
			Placeholder("Your name").
			OnChange(func(s string) { a.name = s }).
			DefaultFocus().
			Grow(1),
		ui.Button("ok", ui.Text("OK")).Primary().OnClick(func() {}),
	).Gap(th.Spacing.M).Padding(th.Spacing.L).Grow(1).Background(ui.TokenSurface)
}

func main() {
	cfg := yoga.Config{Title: "App", Width: 640, Height: 480}
	if err := yoga.Run(cfg, Build); err != nil { panic(err) }
}

Custom title bar (VS Code-style): set `CustomTitleBar: true` in `yoga.Config`, then put menus and tools in `ui.TitleBar(...)` at the top of `Body`. macOS keeps native traffic lights; Windows/Linux get framework min/max/close buttons. Empty title-bar area drags the window; double-click toggles maximize.

GPU entry: //go:build !nogpu + yoga.Run. Headless: //go:build nogpu + shape.NewEngine → yoga.SetResources → ui.BuildFrame. Dual mains live side-by-side in example/*/.

Optional App capabilities (type-asserted by the runtime):

  • Close() — release workers/files when the window closes.
  • OnKey(c *ui.Ctx, k input.KeyEvent) bool (yoga.KeyHook) — global shortcuts after command Dispatch and before focus routing; return true to consume. Prefer c.Commands().Register for palette-visible actions.

Layout DSL (*ui.Node)

ConstructorBehavior
Column(children...)Vertical flex, stretch cross-axis
Row(children...)Horizontal flex, vertically centered
Stack(children...)Z-order layers
Center(child)Fill parent, center child
Spacer()Flex-grow filler
Grid(cols, children...)Equal-width columns (fr tracks)
Scroll(id, child)Clip + scroll; id keys offset
ViewOf(v)Wrap any View so Node modifiers chain
Raw(el)Wrap a bare *layout.Element
HLine(thick, color) / VLine(...)Rules
Icon(icon, size, color)Lucide atlas sprite
Image(id, data)PNG/JPEG from bytes; ImageFile, ImageFS helpers
SVG(id, data)Custom SVG from bytes; SVGFile, SVGFS helpers
TitleBar(children...)Custom window title bar; platform controls auto-included
WindowControls()Min/max/close buttons for undecorated windows (usually via TitleBar)

Children are ui.View. Nil children are skipped. Split a pane into helpers that return ui.View.

Fluent modifiers (chain on *Node): Gap, Padding/PaddingXY/PaddingLeft|Right|Top|Bottom, Margin/MarginXY/sides, Wrap, Grow, Shrink, Width, Height, Frame, Size (font size on Text, else square), Align, Justify, Style(Spec), Background(Token), BackgroundColor, Border/BorderTop|Right|Bottom|Left, BorderStyle, Radius/RadiusTopLeft|TopRight|BottomRight|BottomLeft, Disabled, DefaultFocus.

Alignment constants: ui.AlignStart|Center|End|Stretch, ui.JustifyStart|Center|End|Between.

Fill remaining space with .Grow(1) on the expanding child and its ancestors up to the window root. Root Body trees almost always .Grow(1).Background(ui.TokenSurface).

Use c.Theme().Spacing.* (XXS 2 … XXXL 32) — not magic numbers. Common: S 8, M 12, L 16.

Controlled widgets

Pass current value each frame; callbacks mutate the app struct. Stable unique id strings.

go
ui.TextField("url", app.url).Placeholder("https://…").IconStart(icons.Search).
    OnChange(func(s string) { app.url = s }).OnSubmit(func(s string) { app.go(s) }).Grow(1)

ui.EditableLabel("title", app.title).Placeholder("Untitled").
    OnSave(func(s string) { app.title = s })

ui.Button("send", ui.Text("Send")).Primary().Hint("⌘↵").IconStart(icons.Play).OnClick(app.send)
ui.Checkbox("n", "Notify").Check(app.on).OnToggle(func(v bool) { app.on = v })
ui.Radio("ra", "A").Check(app.radio == 0).OnClick(func() { app.radio = 0 })
ui.Select("lang", opts).Width(200).Selected(i).OnChange(func(v string) { app.lang = v })
ui.Slider("vol", app.vol).Min(0).Max(100).OnFloatChange(func(v float64) { app.vol = v })
ui.Button("tip", ui.Text("Save")).Tooltip("Save document")

Button variants: default Secondary; .Primary() / .Subtle() / .Ghost(). Ghost is text-like (no padding or chrome) for footers; chain .HoverFill() for a hover background. Supports .IconStart() and .Tooltip(). IconButton(id, iconName).

Do not construct NewEditor / NewTable / NewTree inside Body. Construct in Build*, then ui.ViewOf(app.table).Height(220) / .Grow(1).

Theme

theme.Use(name) mutates the live theme in place. Default yoga-dark. theme.Use("system") applies yoga-dark or yoga-light from the OS appearance and keeps syncing while selected. Prefer ui.Token* fills so widgets recolor on switch. c.Theme() for spacing, radius, stroke, typography, semantic colors (th.Success, th.Error, …).

go
ui.Text("hi").Style(ui.Spec{}.TextColor(ui.TokenForegroundMuted))
ui.Column(...).Background(ui.TokenChrome)

Typography helpers: Text, Title, Subtitle, Caption, Strong, Muted. Color/size inherit from parent env (e.g. a Button’s TextColor).

Select a theme before yoga.Run if the app is not dark-default (example/apitest uses yoga-midnight).

Show full SKILL.md (426 more words)Show less

Overlays, focus, async

  • c.Dialogs(), c.Files(), and c.Toasts() are window-owned. BuildFrame lays them out after the body — do not put them in the view tree. Capture c in OnClick to Show.
  • c.Commands() is the window-owned command registry + searchable palette. Register from Body each frame; default toggle is ⌘K / Ctrl+K. Dispatch runs before KeyHook and focus.
  • FileDialog: pure-Go picker with open file/folder and save modes. Footer holds filename (save), filter, optional New Folder (AllowCreateFolder), Cancel, and Open/Select/Save. See widgets.md.
  • c.Dialogs().Show(DialogOpts): custom size, body layout, and footer actions (same modal behavior as FileDialog). ShowInfo / ShowWarning / ShowError / ShowAction / ShowInput are built on this path.
  • Form: labeled settings rows (switch, select, number, text, slider, stepper). Switch: pill toggle for compact rows.
  • Anchored overlays: .Tooltip(text) on any node; Popover (no scrim); ContextMenu (right-click → Menu). Dropdowns/Selects/Menus call c.Overlay themselves.
  • c.Focus().EnsureFocus(w) / .DefaultFocus() on a control when nothing is focused. Tab order = Layout registration order.
  • Background work: mutate app state, then c.Invalidate() (any goroutine). Capture c only for the current frame’s Invalidate closure, or keep a wake func — prefer storing results on the app and calling Invalidate from a handle the runtime already has. Pattern in example/apitest: poll a channel in Body, c.Animate(30*time.Millisecond) while pending.
  • Caret blink / spinner / progress / skeleton: widget calls c.Animate(d) during Layout.

Custom widgets

Implement ui.View:

go
func (w *Panel) Layout(c *ui.Ctx) *layout.Element {
	return ui.Column(...).Grow(1).Layout(c)
}

Low-level: layout.New(layout.Box().…, children...), set Paint / OnMouse, wrap with ui.Raw. Hit-test: e.Frame.Contains(m.X, m.Y); stop bubbling with m.Consumed = true. Overlays: el.Overlay = true then c.Overlay(el).

Store hover in c.Widget(id, func() any { return &state{} }).

Rules of thumb

  • Unique widget ids ("send", "todo-%d"). Colliding ids share hover/caret.
  • Controlled values from the app; never treat TextField as owning the string.
  • Row children that should stretch vertically: parent .Align(ui.AlignStretch).
  • Splitter: ui.Splitter(id, ui.Horizontal|Vertical, a, b).Sizes(240, 0).Grow(1) — 0 means flex. Prefer .Percents(30, 70) for ratio splits; .MinSizes / .MaxSizes (px, 0 max = none); .HandleOnHover() hides the handle line until hover/drag.
  • Drawer: ui.Drawer(id, panel, page).Open(v).Edge(ui.EdgeRight).Overlay().Size(320).Grow(1) — or .Push(); nest for IDE-style terminal + chat; .Swipe(true) for drag gestures. Panel content fills a clipped viewport — use .Grow(1) on the panel view, not fixed width.
  • Icons: Lucide symbols from github.com/mirzakhany/yoga/icons (icons.Search, icons.Plus, icons.Settings, …). Full list in icons/catalog for the component gallery. Regenerate: go run ./cmd/generate-lucide.
  • After async HTTP/highlight: Invalidate or Animate; idle loop otherwise waits forever.
  • Tests/CI: go test ./... and go build -tags nogpu ./....

Example map

PackageWhy read it
example/todoSmallest complete app: form, list, controlled fields
example/galleryShell + editor workspace + widget gallery
example/catalogSidebar catalog + live showcases; custom title bar demo
example/apitestSplitter, editors, Select colors, pending Animate
example/chaparMulti-page nav shell, sub-Layout helpers

Additional resources

© chapar-rest, BSD-3-Clause. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 2 other files in .cursor/skills/yoga-ui of chapar-rest/chapar.

  • SKILL.md
  • examples.md
  • widgets.md

Open the folder on GitHubat commit 5a27fd5

Compare with similar skills

Yoga Go Desktop UI next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Yoga Go Desktop UI compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Yoga Go Desktop UI this skillchapar-rest/chapar714—~2.8kAutomated safety check: PassBSD-3-Clause
Warp One-Time Launch Modalwarpdotdev/warp65k1 repos~3.1kAutomated safety check: PassAGPL-3.0
Design Dnazanwei/design-dna1.9k1 repos~2.1kAutomated safety check: PassMIT
Figma Design to Codewarpdotdev/warp65k4 repos~2.9kAutomated safety check: PassAGPL-3.0
AO Desktop App LauncherOrchestratorInc/agent-orchestrator13k—~2.4kAutomated safety check: PassApache-2.0
Design Guidepaperclipai/paperclip99k1 repos~3.1kAutomated safety check: PassMIT

Similar skills

  • Steps for adding a one-time launch or announcement modal to the Warp desktop GUI, gated by a feature flag and tracked by a settings field.

    65k GitHub starsUsed in 1 repo~3.1k tokens
    Frontend & DesignAuto-check passed
  • Design Dna

    zanwei/design-dna

    Extract, define, and apply design DNA across three dimensions: design system (tokens), design style (qualitative feel), and visual effects (Canvas, WebGL, 3D, particles, shaders, scroll effects…

    1.9k GitHub starsUsed in 1 repo~2.1k tokens
    Frontend & DesignAuto-check passed
  • Figma Design to Code

    warpdotdev/warp

    Turns a Figma frame or component into production code that matches the design, using the Figma MCP server and the project's own design system.

    65k GitHub starsUsed in 4 repos~2.9k tokens
    Frontend & DesignAuto-check passed
  • AO Desktop App Launcher

    OrchestratorInc/agent-orchestrator

    Launches, restarts and troubleshoots the real AO Electron desktop app from a checkout, with isolated or real local data and checks for stale processes.

    13k GitHub stars~2.4k tokensUpdated today
    DevelopmentAuto-check passed
  • Design Guide

    paperclipai/paperclip

    Paperclip UI design system guide for building consistent, reusable frontend components.

    99k GitHub starsUsed in 1 repo~3.1k tokens
    Frontend & DesignAuto-check passed
  • Web Design

    xiaopu-ai/web-design

    Web 视觉设计 SKILL。输入 PRD / 参考 URL / 截图 / 关键词(任意组合),先产出一份标准化 DESIGN.md 设计规范,用户确认后据此生成 UI/UX、视觉、动效、响应式全部达标的 web 代码。专攻 web 端:Landing Page、Portfolio、产品页、博客、个人站、SaaS 介绍页等。当用户说"帮我做个网站""设计一个页面""参考 XX…

    783 GitHub stars~3k tokensUpdated 3 mo ago
    Frontend & DesignAuto-check passed

Works with

Questions about Yoga Go Desktop UI

What does Yoga Go Desktop UI do?

Guides building desktop interfaces with the Yoga Go framework: Body views, layout nodes, widgets, dialogs and headless builds. The skill explains Yoga's mental model: app state is kept between frames and the interface is rebuilt declaratively each frame, much like SwiftUI state.View tree, while the GPU loop skips presenting when nothing visual changed.

When should I use Yoga Go Desktop UI?

Yoga Go Desktop UI fits situations like: writing or changing a Yoga desktop app; adding a widget such as a table, tree or editor; showing dialogs, toasts or file pickers from a click handler; setting up a headless nogpu build of an example.

How do I install Yoga Go Desktop UI in Claude Code?

Run `npx skills add chapar-rest/chapar --skill yoga-ui -a claude-code`. Or copy the skill folder (.cursor/skills/yoga-ui in chapar-rest/chapar) into .claude/skills/yoga-ui in your project. Claude Code loads it when a task matches its description.

How do I install Yoga Go Desktop UI in Codex?

Run `npx skills add chapar-rest/chapar --skill yoga-ui -a codex`. Or copy the skill folder (.cursor/skills/yoga-ui in chapar-rest/chapar) into .agents/skills/yoga-ui in your project. Codex loads it when a task matches its description.

Can I use Yoga Go Desktop UI in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add chapar-rest/chapar --skill yoga-ui -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/yoga-ui, .gemini/skills/yoga-ui, .github/skills/yoga-ui and .opencode/skills/yoga-ui in your project.

What does Yoga Go Desktop UI need to run?

Going by SKILL.md and its folder, Yoga Go Desktop UI needs the command-line tools its instructions call (go). Our summary lists: A Go toolchain; The Yoga module github.com/mirzakhany/yoga.

Does Yoga Go Desktop UI access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Yoga Go Desktop UI safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Yoga Go Desktop UI use?

Yoga Go Desktop UI is published under the BSD-3-Clause licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Yoga Go Desktop UI use?

About 2.8k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Yoga Go Desktop UI?

Skills that share tags, products or a category with Yoga Go Desktop UI: Warp One-Time Launch Modal (warpdotdev/warp, 65k stars), Design Dna (zanwei/design-dna, 1.9k stars), Figma Design to Code (warpdotdev/warp, 65k stars) and AO Desktop App Launcher (OrchestratorInc/agent-orchestrator, 13k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Yoga Go Desktop UI?

chapar-rest (a GitHub organization) maintains it in chapar-rest/chapar, which has 714 GitHub stars. The repository was last updated on October 5, 2026.

Source: chapar-rest/chapar on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.