Skip to content
qianniancnPublic

About

A Go UI framework and component library for cross-platform desktop applications, built on Gio.

Resources

Contributing

Stars

15 stars

Watchers

2 watching

Forks

Repository files navigation

FlowUI

简体中文

Go Reference Go version License

English documentation · 中文文档

FlowUI is a desktop UI framework for Go, built on Gio. It combines a typed MVU runtime with official widgets, layout primitives, declarative styles, window management, asynchronous effects, and deterministic UI testing through focused public packages.

import (
	"github.com/qianniancn/flowui/layout"
	"github.com/qianniancn/flowui/style"
	"github.com/qianniancn/flowui/theme"
	"github.com/qianniancn/flowui/ui"
	"github.com/qianniancn/flowui/widget/button"
	"github.com/qianniancn/flowui/window"
)

FlowUI component showcase

A workspace composed with FlowUI widgets: navigation, charts, forms, date selection, selectable tables, and progress indicators.

Highlights

  • Typed MVU: keep business state in a model, describe changes with messages, and render a read-only view.
  • Desktop components: forms, navigation, overlays, data display, charts, window chrome, and layout primitives.
  • Declarative styling: theme tokens, light and dark themes, component parts, runtime states, transitions, and scoped styles.
  • Application runtime: commands, subscriptions, multiple windows, retained models, and localization.
  • Platform services: optional packages provide native file dialogs, desktop notifications, and system tray integration.
  • Testable by design: deterministic frame, input, time, and application helpers are available in uitest.

Requirements

  • Go 1.26.2 or newer
  • A desktop platform supported by Gio

Install

go get github.com/qianniancn/flowui/ui

Quick Start

Create main.go inside a Go module:

package main

import (
	"fmt"

	"github.com/qianniancn/flowui/layout"
	"github.com/qianniancn/flowui/theme"
	"github.com/qianniancn/flowui/ui"
	"github.com/qianniancn/flowui/widget/button"
	"github.com/qianniancn/flowui/widget/text"
	"github.com/qianniancn/flowui/window"
)

type Model struct {
	Count int
}

type Msg interface{ msg() }

type Inc struct{}
type Dec struct{}

func (Inc) msg() {}
func (Dec) msg() {}

func Update(model *Model, msg Msg) ui.Cmd[Msg] {
	switch msg.(type) {
	case Inc:
		model.Count++
	case Dec:
		model.Count--
	}
	return nil
}

func View(_ *ui.Context, model Model, send ui.Send[Msg]) ui.Widget {
	return layout.Center(
		layout.Column(
			text.New("FlowUI Counter").Size(24),
			text.New(fmt.Sprintf("Count: %d", model.Count)),
			layout.Row(
				button.New("-1").OnClick(func() {
					send(Dec{})
				}),
				button.New("+1").OnClick(func() {
					send(Inc{})
				}),
			).Gap(8),
		).Gap(12),
	)
}

func main() {
	ui.Run(ui.NewProgram(Model{}, Update, View),
		window.Theme(theme.Light()),
		window.Title("FlowUI Counter"),
		window.Size(640, 480),
	)
}

Run it with:

go run .

For a guided walkthrough, read the English Quick Start.

Core Model

FlowUI follows three ownership rules:

  1. Model, messages, and Update own business state. View reads a model value and sends typed messages instead of mutating captured state.
  2. Style owns a widget's box and appearance. Layout containers own how children are measured and positioned.
  3. Keys provide identity across frames. Stable keys retain interaction and animation state for repeated or moving widgets.

Choose the application API that matches the required lifecycle:

API Use it for
ui.Run(ui.Program) The single-window entry point for every MVU program
ui.NewProgram A compact program declaration for a fixed initial model
ui.Application Multiple windows, tray integration, and application-owned lifecycles

Commands run outside the event loop and return results through ui.Send. Subscriptions represent long-lived inputs such as timers or external event streams. The MVU guide and effects guide cover the complete contracts.

Components

Area Included APIs
Content text.New, text.NewLabel, text.NewDescription, image.New, avatar.New, badge.New, chip.New
Actions button.New, button.Group, toggle.NewToggleButton, toggle.NewSegmented, button.NewCloseButton
Forms input.New, input.NewTextArea, toggle.NewCheckbox, toggle.NewSwitch, radiogroup.New, selector.New, combobox.New, date and color pickers
Navigation tabs.New, sidebar.New, tree.New, menu.New, menubar.New, navigation.NewPagination, navigation.NewBreadcrumb, toolbar.New
Overlays dropdown.New, menu.ContextMenu, popover.New, tooltip.New, modal.New, alertdialog.New, toast.NewItem
Data and feedback table.New, progress.Bar, progress.Circle, progress.Meter, spinner.New, slider.New, charts, heatmap.New, gantt.New
Layout layout.Box, surface.New, surface.NewCard, surface.NewPanel, layout.Row, layout.Column, layout.Grid, layout.Scroll, splitpane.New, layout.Stack, layout.Overlay

See the component guide for the complete widget catalog.

Styling and Themes

Styles are immutable declarations that draw colors from the active theme and respond to runtime state. The same declaration follows the active light or dark theme:

activeTheme := theme.Light()

primary := style.New().
	Background(style.Solid(activeTheme.Colors.Tones[theme.TonePrimary].Fill)).
	TextColor(style.Solid(activeTheme.Colors.Tones[theme.TonePrimary].OnFill)).
	Radius(8).
	Cursor(style.CursorPointer).
	On(style.Hovered, style.New().Background(style.Solid(activeTheme.Colors.Tones[theme.TonePrimary].Hover))).
	On(style.Pressed, style.New().Background(style.Solid(activeTheme.Colors.Tones[theme.TonePrimary].Pressed)).Scale(0.96))

save := button.New("Save").Style(primary)

The runtime requires an explicit theme. Pass window.Theme(theme.Light()) or window.Theme(theme.Dark()); use window.CustomizeTheme for focused token changes. Component packages supply their own default appearance. Compound controls expose named parts such as style.PartContent, style.PartTrack, style.PartIndicator, and style.PartPanel for focused customization. FlowUI includes English and Chinese component strings; window.LanguageAuto follows the host language.

The style and theme guide documents precedence, parts, colors, geometry, transitions, and bundled font setup.

FlowUI uses system font fallback by default. For reproducible rendering, parse an embedded TTF, OTF, or TTC with opentype.ParseCollection (gioui.org/font/opentype), assign the faces to theme.Fonts.Collection, and set theme.Fonts.SystemFonts = false.

The core maintains one default design system in theme, with light and dark modes. Applications can use theme.Light() / theme.Dark() directly or build a custom token theme with the public theme APIs. For a different component structure, compose the headless controls in widget/base.

Public Packages

Package Responsibility
ui MVU program, context, widget contract, and application lifecycle
widget/<component> Official fully-rendered components
widget/base Headless behavior, focus, and semantics for custom designs
layout Layout containers and the common box host
style Immutable declarations, cascade, and tokens
theme Semantic colors, geometry, typography, and motion tokens
draw Low-level brushes, borders, shadows, paths, and transforms
animation Reusable tween, spring, and timeline primitives
window Native window options and locale configuration
uitest Deterministic widget and application test harnesses

Start with the interactive component showcase: go run ./examples/showcase. Its 67 pages cover every public widget package, with search, live demos, usage snippets, and light/dark modes. The interface defaults to English and opens on the interactive workspace overview; it can be switched to Chinese.

Focused default-theme examples also live in this module: go run ./examples/counter, go run ./examples/buttons, go run ./examples/inputs, go run ./examples/base_controls for headless bases with custom visuals, and go run ./examples/close_guard for a native close-request guard.

Documentation

Resource Purpose
Documentation English task-oriented guide from first app through advanced features
中文文档 中文教程和组件说明
Package reference Public Go API
docs/architecture.md Dependency direction, state ownership, overlays, and effects
explorer/README.md Per-window native open and save dialogs
notify/README.md Cross-platform native notifications
systray/README.md Cross-platform system tray lifecycle and native menus
CONTRIBUTING.md Development workflow and contribution rules

Applications use ui for MVU and widget/<component>, layout, style, draw, and window according to responsibility. explorer, notify, and systray are optional platform services. Applications must not import packages under internal. The repository root intentionally contains no Go package.

Testing

Run the complete project checks from the repository root:

go test ./...
go vet ./...

uitest is intended for component and application tests; it is not required by applications at runtime. See the testing guide.

Contributing

Contributions are welcome. Read CONTRIBUTING.md before submitting a change.

License

FlowUI is available under the MIT License.

About

A Go UI framework and component library for cross-platform desktop applications, built on Gio.

Resources

Contributing

Stars

15 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages