RepoPilotOpen in app →

andlabs/ui

Platform-native GUI library for Go.

Mixed

Stale — last commit 4y ago

weakest axis
Use as dependencyConcerns

non-standard license (Other); last commit was 4y ago…

Fork & modifyMixed

no tests detected; no CI workflows detected…

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isMixed

last commit was 4y ago; no CI workflows detected

  • 4 active contributors
  • Other licensed
  • Stale — last commit 4y ago
Show all 8 evidence items →
  • Small team — 4 contributors active in recent commits
  • Single-maintainer risk — top contributor 94% of recent commits
  • Non-standard license (Other) — review terms
  • No CI workflows detected
  • No test directory detected
What would change the summary?
  • Use as dependency ConcernsMixed if: clarify license terms; 1 commit in the last 365 days
  • Fork & modify MixedHealthy if: add a test suite
  • Deploy as-is MixedHealthy if: 1 commit in the last 180 days

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Great to learn from" badge

Paste into your README — live-updates from the latest cached analysis.

RepoPilot: Great to learn from
[![RepoPilot: Great to learn from](https://repopilot.app/api/badge/andlabs/ui?axis=learn)](https://repopilot.app/r/andlabs/ui)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/andlabs/ui on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: andlabs/ui

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/andlabs/ui shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Stale — last commit 4y ago

  • 4 active contributors
  • Other licensed
  • ⚠ Stale — last commit 4y ago
  • ⚠ Small team — 4 contributors active in recent commits
  • ⚠ Single-maintainer risk — top contributor 94% of recent commits
  • ⚠ Non-standard license (Other) — review terms
  • ⚠ No CI workflows detected
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live andlabs/ui repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/andlabs/ui.

What it runs against: a local clone of andlabs/ui — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in andlabs/ui | Confirms the artifact applies here, not a fork | | 2 | License is still Other | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 1479 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>andlabs/ui</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of andlabs/ui. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/andlabs/ui.git
#   cd ui
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of andlabs/ui and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "andlabs/ui(\\.git)?\\b" \\
  && ok "origin remote is andlabs/ui" \\
  || miss "origin remote is not andlabs/ui (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
  && ok "license is Other" \\
  || miss "license drift — was Other at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "main.go" \\
  && ok "main.go" \\
  || miss "missing critical file: main.go"
test -f "control.go" \\
  && ok "control.go" \\
  || miss "missing critical file: control.go"
test -f "window.go" \\
  && ok "window.go" \\
  || miss "missing critical file: window.go"
test -f "draw.go" \\
  && ok "draw.go" \\
  || miss "missing critical file: draw.go"
test -f "pkgui.h" \\
  && ok "pkgui.h" \\
  || miss "missing critical file: pkgui.h"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 1479 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~1449d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/andlabs/ui"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

andlabs/ui is a cross-platform GUI library for Go that wraps libui (a native C library) to provide platform-native widgets on Windows, macOS, and Linux. It exposes high-level Go types like Button, Entry, Window, and Table that compile to native OS controls (Win32 API on Windows, Cocoa on macOS, GTK+ 3 on Linux), eliminating the need to write platform-specific GUI code. Monolithic flat structure: 50+ control-specific .go files (button.go, checkbox.go, table.go, etc.) at root level, each wrapping a single libui control type. Core abstraction is the Control interface (control.go). Platform-specific linking handled via link_*.go files (one per OS/arch pair: link_darwin_amd64.go, link_windows_386.go, etc.). C FFI boilerplate in pkgui.c/pkgui.h. Windows requires manifest subpackage (winmanifest/).

👥Who it's for

Go developers building lightweight desktop applications who want native UI controls without Electron or Qt overhead. This appeals to systems programmers and tool authors who need cross-platform GUIs with minimal dependencies and small binary size.

🌱Maturity & risk

This is mid-alpha experimental software (explicit in README). The codebase is stable enough for the 5 included examples to run, but feature-complete on only some platforms, with known bugs on certain OSes, and missing substantial functionality. No CI/test suite is visible in the file list; no GitHub Actions or TravisCI config present. Last commit date unknown but the TODO.md file suggests active (if slow) development.

High risk for production use: single maintainer (andlabs), mid-alpha status means breaking changes are expected, no automated tests visible in the repo, pre-compiled libui binaries checked into git (libui_darwin_amd64.a, libui_linux_amd64.a, etc.) creating maintenance burden and bloat. Dependencies on obsolete Windows Vista SP2 support and GTK+ 3.10+ create platform support fragmentation.

Active areas of work

Project appears dormant—no recent activity visible in file list, but presence of TODO.md and mid-alpha status suggests work-in-progress. The examples (controlgallery.go, drawtext.go, histogram.go, table.go, updateui.go) indicate the maintainer is testing core features. No open PRs or branch data provided.

🚀Get running

  1. Install dependencies: sudo apt-get install libgtk-3-dev (Debian/Ubuntu), sudo dnf install gtk3-devel (Fedora), or native headers on macOS/Windows. 2. Clone: git clone https://github.com/andlabs/ui.git && cd ui. 3. Build an example: cd examples && go build -o controlgallery controlgallery.go && ./controlgallery.

Daily commands: No dev server needed. For examples: cd examples && go build -o appname appname.go && ./appname (e.g., go build -o histogram histogram.go && ./histogram). Requires native libui binaries already present or linked during build via cgo.

🗺️Map of the codebase

  • main.go — Entry point and initialization for the libui Go bindings; sets up platform-specific behavior and library initialization.
  • control.go — Core abstraction defining the Control interface that all UI widgets must implement; foundational to the entire control hierarchy.
  • window.go — Window implementation and lifecycle management; every GUI application starts with a Window and event loop.
  • draw.go — Drawing primitives and canvas API for custom rendering; critical for advanced graphics and the Area widget.
  • pkgui.h — C header bindings to libui C library; all platform calls pass through this interface.
  • areahandler.go — Handler interface for the Area widget's draw, mouse, and keyboard events; essential for custom drawing applications.
  • tablemodel.go — Data model abstraction for Table widget; defines the contract for populating and updating tabular data.

🛠️How to make changes

Add a new simple widget (e.g., new button variant)

  1. Create new .go file for widget (e.g., togglebutton.go) implementing the Control interface from control.go (togglebutton.go)
  2. Implement required Control methods: Destroy(), LibuiControl(), and Handle() (control.go)
  3. Add platform-specific C bindings in pkgui.c for your widget creation and property setters (pkgui.c)
  4. Export your widget constructor in the main package (public function name) (togglebutton.go)
  5. Add example usage in examples/controlgallery.go to demonstrate the new widget (examples/controlgallery.go)

Create a custom drawing application

  1. Create a window and add an Area widget via box layout (window.go)
  2. Implement AreaHandler interface from areahandler.go with Draw(), MouseEvent(), and KeyEvent() methods (areahandler.go)
  3. Use the drawing API (paths, brushes, text) in your Draw() handler from draw.go and drawtext.go (draw.go)
  4. Set your handler on the Area via area.SetHandler() (area.go)
  5. Call area.QueueRedrawAll() to trigger redraws from your event handlers (area.go)

Implement a data-driven table view

  1. Create a struct that implements the TableModel interface from tablemodel.go (tablemodel.go)
  2. Implement RowCount(), ColumnCount(), Value(), SetValue() and ColorForRow() methods (tablemodel.go)
  3. Create a Table widget via table.go and call table.AppendTextColumn() for each column (table.go)
  4. Set your data model on the table via table.SetModel(myModel) (table.go)
  5. Add the table to a container (Box, Window, etc.) and set up event handlers (box.go)

🔧Why these technologies

  • cgo & C bindings — Go lacks native platform GUI APIs; libui abstracts platform differences (Cocoa on macOS, Win32 on Windows, GTK+ on Linux) through C interface.
  • libui C library (vendored as .a files) — Single cross-platform abstraction layer eliminates need to implement three separate platform backends in Go; reduces code duplication and ensures feature parity.
  • Control interface abstraction — Polymorphism in Go allows any widget (button, text, table, etc.) to be treated uniformly for layout, event binding, and lifecycle management without reflection.
  • Handler interfaces (AreaHandler, TableModel) — Inversion of control pattern lets user code provide custom behavior (drawing, data) without modifying the library; loose coupling between widgets and application logic.

⚖️Trade-offs already made

  • Mid-alpha stability with feature incompleteness

    • Why: Binding a moving C library (libui Alpha 4.1) to Go requires ongoing maintenance; the project prioritizes correctness over breadth of features.
    • Consequence: Users must expect missing functionality and potential bugs on specific platforms; suitable only for small apps and prototypes, not production GUI software.
  • Platform-native widgets rather than custom rendering

    • Why: Uses OS-provided controls (buttons, text boxes, tables) instead of drawing them from scratch; ensures look-and-feel consistency with host OS.
    • Consequence: Limited customization of widget appearance; some advanced styling features unavailable; behavior may differ subtly across platforms.
  • Single-threaded event loop (main.Run())

    • Why: Matches how native OS event loops work; simplifies synchronization with platform APIs and prevents race conditions on UI state.
    • Consequence: Long-running operations block the UI; requires goroutines + channels for responsive applications; no built-in async/await pattern.
  • Vendored libui binaries (.a files) for each platform/architecture

    • Why: Avoids forcing users to build libui from source; pre-compiled binaries simplify installation.
    • Consequence: Cannot customize or patch libui behavior; repository size larger; maintainers must rebuild and test binaries for each platform.

🚫Non-goals (don't propose these)

  • Web-based UI rendering; this is platform-native only (Cocoa, Win32, GTK+).
  • Async/await or non-blocking UI primitives; applications must manage concurrency via goroutines and channels.
  • High-fidelity custom styling/the

🪤Traps & gotchas

  1. Precompiled binaries required: libui_*.a files are checked into git at root level; no build process generates them. You must use the exact Go/OS/arch combination the .a was compiled for. 2. Windows manifest mandatory: Any Windows build must import _ "github.com/andlabs/ui/winmanifest" or provide custom .rc/.syso, or the app will lack Common Controls v6 and fail. 3. cgo non-negotiable: All platforms require cgo; pure-Go builds are impossible. 4. No async I/O model: All UI operations block the main thread; long-running tasks will freeze the GUI. 5. GTK+ 3.10+ hard requirement on Linux: Older Ubuntu/Debian LTS releases may not meet this.

🏗️Architecture

💡Concepts to learn

  • cgo (C Foreign Function Interface) — Every widget in ui is implemented via cgo calls to C libui functions; understanding cgo is essential to debugging platform-specific bugs or extending ui with new controls
  • Platform abstraction layer — ui's entire design goal is to hide Win32 API, Cocoa, and GTK+ behind a unified Go interface; studying how link_*.go and pkgui.c achieve this teaches cross-platform library design
  • Binary linking & static libraries (.a files) — libui is distributed as precompiled .a binaries checked into git; understanding how cgo links these during compilation is crucial for platform support and debugging linker errors
  • Event-driven GUI architecture (main event loop) — ui wraps the native OS event loop (Win32 message pump, Cocoa run loop, GTK+ g_main_loop); knowing how event handlers in areahandler.go and window.go dispatch callbacks is core to writing responsive GUIs
  • Build tags (// +build) — ui uses build tags in link_*.go to conditionally compile platform-specific code; mastering this pattern is essential for contributing cross-platform fixes
  • Resource embedding (Windows .RC and .syso files) — Windows builds require manifest resources to be compiled into the binary via windres; this Windows-specific build step is non-obvious but mandatory for proper Common Controls support
  • Immediate mode vs. retained mode GUI — ui is retained-mode (create widgets once, mutate them); this contrasts with immediate-mode frameworks like Iced; understanding the tradeoff explains ui's threading model and performance characteristics
  • andlabs/libui — The upstream C library that andlabs/ui wraps—essential to understanding the feature set and limitations of the Go bindings
  • fyne-io/fyne — Alternative pure-Go cross-platform GUI library with built-in widgets and no C dependencies—competes on simplicity but uses OpenGL rendering instead of native controls
  • gotk3/gotk3 — GTK+ 3 bindings for Go—deeper GTK+ access on Linux but not cross-platform to Windows/macOS
  • getlantern/systray — Complementary Go library for native menu bar/system tray integration—often used with ui for complete desktop apps
  • therecipe/qt — Qt bindings for Go offering full-featured native UI—more mature than ui but heavier dependency and larger binaries

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add platform-specific unit tests for control implementations

The repo contains ~20 control files (button.go, checkbox.go, entry.go, etc.) with no visible test files (*_test.go). Since this is a platform-native library with different implementations per OS (evidenced by link_darwin_amd64.go, link_windows_amd64.go, link_linux_amd64.go), adding tests would validate that controls behave consistently across platforms and catch platform-specific bugs early.

  • [ ] Create button_test.go with tests for Button creation, enabling/disabling, and text setting
  • [ ] Create entry_test.go with tests for Entry text manipulation and event handling
  • [ ] Create checkbox_test.go with tests for state changes and callbacks
  • [ ] Use build tags (+build windows, +build darwin, +build linux) to test platform-specific behavior in link_*.go implementations
  • [ ] Run tests across all three platforms (Windows, macOS, Linux) in local development

Complete the truncated Status section in README.md and add API stability documentation

The README.md Status section is incomplete (text ends mid-sentence with 't'). Since the package is marked 'mid-alpha' with stability concerns, contributors and users need clear guidance on which APIs are stable vs. experimental. This is critical for setting expectations and preventing breaking changes.

  • [ ] Complete the truncated paragraph in README.md Status section explaining current stability limitations
  • [ ] Create STABILITY.md documenting which control types and APIs are considered stable (e.g., 'Button is stable', 'Table implementation is experimental on Linux')
  • [ ] Reference specific known issues from TODO.md in the stability documentation
  • [ ] Add a 'Breaking Changes' section to README.md linking to STABILITY.md for version upgrade guidance

Add integration tests for the example programs and CI workflow

The repo contains 5 example programs (controlgallery.go, histogram.go, table.go, etc.) but no verification that they compile or run. Since this is a cross-platform GUI library, a GitHub Actions workflow that compiles examples on Windows, macOS, and Linux runners would catch platform-specific build failures early and prevent regressions.

  • [ ] Create .github/workflows/examples-build.yml that builds each example in examples/*.go on ubuntu-latest, macos-latest, and windows-latest
  • [ ] Add conditional steps to install platform dependencies (gtk3-dev on Linux via apt-get, as documented in README.md)
  • [ ] Include a step that verifies examples compile without warnings using CGO_ENABLED=1 go build
  • [ ] Document in CONTRIBUTING.md (create if missing) that contributors should test examples build locally before submitting PRs

🌿Good first issues

  • Add unit tests for the five control types in button.go, entry.go, and slider.go—currently none exist in the repo (no test files visible)
  • Document the Control interface contract in control.go with code examples showing how to implement a custom control wrapper around a libui type
  • Add a simple form validation example to examples/ demonstrating error handling and disabling submit buttons—visible gap in the 5 existing examples

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 70a69d6 — Merge pull request #385 from Vorstenbosch/added-example-for-ui-update (andlabs)
  • d219f06 — Differentiating between UI changes from the main thread and another goroutine (Vorstenbosch)
  • f9ad173 — Added an example that shows how to update the UI (Vorstenbosch)
  • 867a9e5 — Oops (andlabs)
  • add47bf — And rewrote the README. Once I test winmanifest on windows/386 I'll push this at last! (andlabs)
  • 71aba62 — Added a winmanifest package for including a generic Windows manifest. Now to just rewrite the README. (andlabs)
  • 4c4827d — Moved the examples into their final places. (andlabs)
  • 7b7a2a7 — And removed the old test. (andlabs)
  • 731fa9c — And finished the table example program. (andlabs)
  • 5b9b35a — And moved the other link files back. It works! (andlabs)

🔒Security observations

This is a mid-alpha GUI library with moderate security concerns. The primary issues are: (1) pre-compiled binary artifacts without integrity verification mechanisms, (2) opaque binary resource files, and (3) C interop without documented security boundaries. The alpha status and lack of formal security review process are additional concerns. Recommendations focus on providing transparency and verification mechanisms for binary artifacts, documenting security practices at the Go-C boundary, and establishing consistent security review procedures across platforms.

  • High · Pre-compiled Binary Libraries Without Verification — libui_darwin_amd64.a, libui_linux_386.a, libui_linux_amd64.a, libui_windows_386.a, libui_windows_amd64.a. The repository contains pre-compiled static libraries (libui_*.a files) for multiple platforms and architectures. These binaries are not accompanied by checksums, signatures, or build scripts for verification. An attacker could substitute malicious binaries, and users would have no way to verify authenticity or integrity. Fix: Provide SHA256/SHA512 checksums or cryptographic signatures for all binary artifacts. Document the build process and source of binaries. Consider building from source or providing build instructions instead of distributing pre-compiled binaries.
  • High · Pre-compiled Windows Resource Files (syso) — winmanifest/winmanifest_windows_386.syso, winmanifest/winmanifest_windows_amd64.syso. Windows manifest resource files (winmanifest_windows_*.syso) are pre-compiled binary files. These are difficult to audit and could potentially contain malicious code or security misconfigurations. No documentation on their contents or build process is evident. Fix: Provide source files (e.g., .rc/.xml) for these resources. Document the build process. Consider generating these files during the build process rather than distributing pre-compiled binaries.
  • Medium · C Code Integration Without Clear Security Boundaries — pkgui.c, pkgui.h, and all .go files with cgo bindings. The codebase uses cgo to integrate C libraries (libui) and includes C source files (pkgui.c, pkgui.h). While C/cgo integration is necessary for this library, there is no evident documentation of security considerations, input validation at the Go-C boundary, or memory safety practices. Fix: Add security documentation outlining memory safety practices, input validation at the Go-C boundary, and potential attack vectors when using this library. Implement defensive programming practices in C code. Consider fuzzing the Go-C interface.
  • Medium · Platform-Specific Code Without Standardized Security Review — link_darwin_amd64.go, link_linux_386.go, link_linux_amd64.go, link_windows_386.go, link_windows_amd64.go. Multiple platform-specific link files (link_*.go) suggest platform-dependent implementations. Without clear security review processes or documentation, platform-specific vulnerabilities could be introduced and not caught uniformly across all supported platforms. Fix: Document security review procedures for each platform. Ensure consistent security practices across all platform implementations. Add platform-specific security testing to CI/CD pipeline.
  • Low · Alpha/Unstable Software Quality — README.md. The README explicitly states this is 'mid-alpha' software with stability as a 'work-in-progress' and potential bugs on certain platforms. While not a direct vulnerability, using this in production could expose applications to unexpected behavior or security issues. Fix: Clearly communicate the alpha status to users. Implement comprehensive testing before production use. Consider establishing clear stability/security milestones before recommending for production deployments.
  • Low · No Visible Dependency Management Configuration — Repository root. No go.mod, go.sum, or similar dependency management files are visible in the provided structure. This makes it difficult to track and audit dependencies for known vulnerabilities. Fix: Ensure go.mod and go.sum are present and committed to version control. Regularly run 'go list -json -m all' and use tools like 'go list -m all | nancy sleuth' to check for known vulnerabilities.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · andlabs/ui — RepoPilot