Fyne — API Surface#

API types#

Library (primary) + CLI (deprecated, migrated to fyne.io/tools) + Plugin/Extension system

Fyne is consumed almost entirely as a Go library. There is no HTTP server, no gRPC service, no REST API. Applications import the packages and call constructor functions. The extension points (custom widgets, custom themes, URI repositories, cloud providers, embedded drivers) are all interface-based.


REST/HTTP API#

Not applicable. Fyne does not expose or consume an HTTP API.


gRPC API#

Not applicable.


CLI (deprecated)#

  • Framework: github.com/urfave/cli/v2
  • Status: The cmd/fyne binary inside this repo is deprecated as of v2.x. It prints a notice at startup and directs users to fyne.io/tools/cmd/fyne.
  • Command structure:
CommandPurpose
bundleEmbed static resources into Go source as fyne.Resource values
buildCross-compile a Fyne app for a target OS (wraps go build with platform toolchains)
packagePackage a built binary into a platform-native distributable (.app, .exe, .apk, etc.)
installBuild + install to the running device or emulator
releasePackage + sign for release (App Store, Play Store, Windows Store)
getDeprecated equivalent of go get for Fyne apps
serveServe a Fyne app as a WASM application in a browser
translateExtract i18n strings for the lang package
envPrint the Fyne/Go environment (GOPATH, CGO state, platform details)
versionPrint the fyne CLI version
vendorDeprecated: use go mod vendor instead
  • Flag patterns: Each subcommand owns its flags via cli.Command.Flags. No global persistent flags except --version. Flags are straightforward string/bool parameters (OS target, icon path, app ID, release mode).

Library API#

This is the primary API surface. Fyne is organized into several cooperating public packages, with the root package fyne.io/fyne/v2 defining all contracts and the remaining packages providing implementations.

Root package (fyne.io/fyne/v2)#

The root package exports only interfaces and value types — no concrete implementations. This is the stable contract that all application code depends on.

Key exported interfaces:

InterfacePurpose
AppTop-level application lifecycle: NewWindow, Run, Quit, Settings, Preferences, Storage, Metadata
WindowOS window abstraction: SetContent, Show, Hide, Resize, SetTitle, SetMainMenu, RequestFocus
CanvasDrawing surface: Content, SetContent, Size, Scale, Focus, Overlays, Capture
CanvasObjectBase for all visible objects: Size, Position, Move, Resize, Visible, Show, Hide, Refresh, MinSize
WidgetExtends CanvasObject with CreateRenderer() WidgetRenderer — the custom widget entry point
WidgetRendererRenderer side of the Widget split: Layout, MinSize, Refresh, Objects, Destroy
ThemeColor, icon, font, and size tokens: Color(ThemeColorName, ThemeVariant), Icon(ThemeIconName), Font(TextStyle), Size(ThemeSizeName)
LayoutCustom layout algorithm: Layout([]CanvasObject, Size), MinSize([]CanvasObject) Size
DriverBackend abstraction (normally not used directly by app code)
LifecycleApp lifecycle hooks: SetOnStarted, SetOnStopped, SetOnEnteredForeground, SetOnExitedForeground
StorageApp-scoped file storage: RootURI, List, Open, Save
URI / URIReadCloser / URIWriteCloserCross-platform resource references
CloudProviderExtension point for cloud sync backends

Key exported value types: Animation, AppMetadata, Container, Delta, DragEvent, HardwareKey, KeyEvent, PointEvent, Position, ScrollEvent, Size, TextStyle, ThemeColorName / ThemeIconName / ThemeSizeName (string aliases for semantic tokens).

Key free functions: CurrentApp(), SetCurrentApp(App), CurrentDevice(), Do(func()) (marshal work to UI thread), NewAnimation(duration, fn).


app package#

Entry point for creating an application.

FunctionDescription
app.New() fyne.AppCreate an app, picking up app ID from FyneApp.toml
app.NewWithID(id string) fyne.AppCreate an app with an explicit ID (for preferences isolation)
app.SetMetadata(fyne.AppMetadata)Override build-time metadata at runtime
app.SetDriverDetails(fyne.App, embedded.Driver)Wire a custom embedded driver (used with driver/embedded)

widget package#

The largest user-facing package (63 exported constructor functions). All widgets follow the same pattern: a public struct embedding widget.BaseWidget (from the internal package), a New* constructor, and data-binding variants (New*WithData).

Standard widgets:

WidgetDescription
ButtonLabelled button with optional icon, OnTapped callback, importance level
Entry / MultiLineEntry / PasswordEntryText input; also NewEntryWithData(binding.String)
LabelRead-only text, supports alignment and style
Check / CheckGroupBoolean and multi-select checkboxes
RadioGroupSingle-select radio buttons
Select / SelectEntryDropdown selector; SelectEntry allows free text
SliderNumeric range input
ProgressBar / ProgressBarInfiniteDeterminate and indeterminate progress
List / GridWrap / TableVirtualized list, grid, and table with virtual item recycling via createItem/updateItem callbacks
TreeHierarchical tree view
FormLabel-field form with submit/cancel; FormItem pairs
AccordionCollapsible sections
CardContent card with title and subtitle
RichTextStyled text with embedded segments (TextSegment, ImageSegment, HyperlinkSegment, ListSegment, etc.)
HyperlinkClickable link
IconImage/icon display
FileIconFile-type icon derived from URI extension
PopUp / PopUpMenuOverlay popups
MenuMenu bar from fyne.Menu
SeparatorVisual divider
ToolbarRow of ToolbarItem actions
ActivityAnimated activity indicator (since 2.5)
CalendarDate picker (since 2.7)
DateEntryText entry with calendar popup
TextGridLow-level fixed-width grid for terminal-style UIs

API style: All constructors are top-level functions (NewButton, NewLabel, etc.) returning concrete pointer types. No builder pattern. Callback functions are assigned directly to exported struct fields (OnTapped func(), OnChanged func(string)), not registered via method calls. Data-binding variants use New*WithData(binding.X).


container package#

Combines a fyne.Layout with child objects. All constructors return *fyne.Container.

ConstructorLayout
NewVBox / NewHBoxVertical / horizontal box with spacers
NewBorder(top, bottom, left, right, ...rest)Border layout
NewCenterCenter single child
NewGridWithColumns(n) / NewGridWithRows(n)Fixed-column/row grid
NewAdaptiveGrid(n)Grid that flips from columns to rows on narrow screens
NewGridWrap(size)Wrapping grid with fixed cell size
NewStackStack (z-order, all children full size)
NewMaxAlias for stack (deprecated name)
NewPaddedAdd theme-standard padding around content
NewScroll / NewHScroll / NewVScrollScrollable container
NewHSplit / NewVSplitResizable split pane
NewAppTabs / NewDocTabsTab containers (fixed tabs vs closeable doc tabs)
NewNavigationNavigation stack (push/pop)
NewMultipleWindowsMDI-style inner windows
NewInnerWindowIndividual MDI window within MultipleWindows
NewThemeOverrideApply a different theme to a subtree
NewClipClip child to container bounds

canvas package#

Primitive drawing objects that are fyne.CanvasObject but not widgets.

TypeDescription
RectangleFilled or stroked rectangle with optional corner radius
CircleFilled circle
LineLine segment
Arc / PieArc / DoughnutArcArc primitives (since 2.6)
PolygonRegular polygon
ImageBitmap or SVG image (from file, URI, resource, reader, or image.Image)
RasterPixel-by-pixel raster callback
TextStyled text primitive
LinearGradient / RadialGradientGradient fills

Free functions: canvas.Refresh(obj) (force repaint), canvas.RecolorSVG([]byte, color.Color).

Animation constructors: NewColorRGBAAnimation, NewPositionAnimation, NewSizeAnimation — all return *fyne.Animation driven by fyne.Animation.Start()/Stop().


layout package#

Returns fyne.Layout implementations (used with container.New(layout, ...objects)). Mirrors the layouts available via container.New* shortcuts but as standalone objects for custom containers.

Available: NewVBoxLayout, NewHBoxLayout, NewCustomPaddedVBoxLayout, NewCustomPaddedHBoxLayout, NewBorderLayout, NewCenterLayout, NewFormLayout, NewAdaptiveGridLayout, NewGridLayout(cols), NewGridLayoutWithColumns, NewGridLayoutWithRows, NewGridWrapLayout, NewPaddedLayout, NewRowWrapLayout, NewCustomPaddedLayout(padTop, padBottom, padLeft, padRight).

The Spacer struct can be added to box layouts to fill remaining space.


dialog package#

Modal dialogs, each with a New* constructor (returns the dialog for configuration before display) and a Show* convenience function (creates and shows immediately).

DialogDescription
ConfirmDialogYes/No confirmation
EntryDialogText input with OK/Cancel
CustomDialogArbitrary content with configurable buttons
CustomDialog (no buttons)NewCustomWithoutButtons
CustomConfirmDialogCustom content + Confirm/Cancel buttons
ColorPickerDialogRGBA color picker
FileDialogFile open/save with filter support
FolderOpenDialogFolder selection (via FileDialog.SetOnClosed)
InformationDialogSingle-message info box
ErrorDialogError display (formats error)
ProgressDialogProgress bar modal
ProgressInfiniteDialogInfinite progress bar modal

The Dialog interface (Show, Hide, SetDismissText, SetOnClosed, Resize) is the common contract.


theme package#

Access to the active theme’s semantic tokens. All functions read from fyne.CurrentApp().Settings().Theme().

  • Color accessors (24 functions): BackgroundColor, ButtonColor, DisabledColor, ErrorColor, FocusColor, ForegroundColor, HoverColor, InputBackgroundColor, PrimaryColor, SelectionColor, SuccessColor, WarningColor, etc.
  • Font accessors (8 functions): DefaultTextFont, TextBoldFont, TextItalicFont, TextMonospaceFont, etc.
  • Icon accessors (one per built-in icon): ~60 functions returning fyne.Resource (e.g., theme.HomeIcon(), theme.SearchIcon(), theme.SettingsIcon()).
  • Size accessors (9 functions): InnerPadding, LineSpacing, Padding, ScrollBarSize, SeparatorThicknessSize, TextSize, etc.
  • Theme objects: LightTheme() / DarkTheme() return fyne.Theme with fixed variant. DefaultTheme() returns the built-in adaptive theme.

data/binding package#

Observer-pattern reactive bindings over Go primitives. Central to connecting non-UI data to widget display.

Typed binding interfaces (all implement DataItem): Bool, Bytes, Float, Int, Rune, String, URI, Untyped — plus collection variants: BoolList, FloatList, IntList, StringList, UntypedList, UntypedMap, StringStringMap.

Generic variants (Go 1.18): Item[T], ExternalItem[T], NewItem[T], BindItem[T].

Constructors:

  • NewBool(), NewFloat(), NewInt(), NewString(), etc. — in-memory binding
  • BindBool(*bool), BindFloat(*float64), etc. — wrap an existing Go variable
  • NewDataListener(fn func()) — fire a callback on any change

Converters (cross-type bindings): BoolToString, FloatToString, IntToFloat, FloatToInt, IntToString, StringToBool, StringToFloat, StringToInt, StringToURI, URIToString, plus format-string variants.

Boolean combinators: Not(Bool) Bool, And(...Bool) Bool, Or(...Bool) Bool.


storage and storage/repository packages#

Abstractions for cross-platform file/URI access.

storage package (application-layer API):

FunctionDescription
NewFileURI(path)Create a file:// URI from a local path
NewURI(s) / ParseURI(s)Parse a URI string
OpenFileFromURI(uri)Open for reading
SaveFileToURI(uri)Open for writing
ListerForURI(uri)Get a fyne.ListableURI
Exists, Delete, DeleteAllFile operations
Parent, ChildURI navigation
NewExtensionFileFilter, NewMimeTypeFileFilterCreate file dialog filters
LoadResourceFromURILoad a fyne.Resource

storage/repository package (extension point for custom URI schemes):

The Repository interface and its capability sub-interfaces allow third-party code to register new URI schemes (e.g., s3://, sftp://):

InterfaceCapability added
RepositoryBase: Exists, Reader, CanRead, Destroy
WritableRepositoryWriter, CanWrite
AppendableRepositoryAppender, CanAppend
ListableRepositoryList, CanList
HierarchicalRepositoryParent, Child
CopyableRepositoryCopy
MovableRepositoryMove
DeleteAllRepositoryDeleteAll
CustomURIRepositoryOverride URI stringification

Registration: storage/repository.Register(scheme, Repository). Applications or libraries call this in init() or startup to add new URI schemes. The app package registers file://, http://, https:// at startup.


driver/* packages (extension points)#

Public packages that expose platform-specific capabilities via type assertions.

PackageInterfaceUse
driver/desktopDriverCreateSplashWindow, CurrentKeyModifiers
driver/desktopCanvasRaw OnKeyDown/OnKeyUp callbacks
driver/desktopCursorCustom cursor images; Cursorable widget interface
driver/desktopHoverableMouseIn/MouseMoved/MouseOut for desktop hover
driver/mobileDriverGoBack() — trigger OS back navigation
driver/mobileKeyboardableSoft keyboard type hints
driver/mobileTouchableRaw touch events (beyond tap abstraction)
driver/embeddedDriverRender(image.Image), Run(func()), ScreenSize, Queue — full custom hardware backend (since 2.7)
driver/softwareRenderCanvas(fyne.Canvas, fyne.Theme) image.Image / Render(obj, theme) image.Image for headless rendering

Usage pattern: if d, ok := fyne.CurrentApp().Driver().(desktop.Driver); ok { d.CreateSplashWindow() }.


test package#

A complete test support library for widget authors and app developers.

FunctionDescription
test.NewApp()Create a headless app backed by the software renderer
test.NewTempApp(t)Create + register cleanup for testing.TB
test.NewCanvas() / NewCanvasWithPainterWindowless canvas for layout/render tests
test.Tap(obj) / DoubleTapSimulate tap events
test.Drag(canvas, pos, dx, dy)Simulate drag
test.Scroll(canvas, pos, dx, dy)Simulate scroll
test.MoveMouse(canvas, pos)Simulate hover
test.FocusNext / FocusPreviousNavigate focus
test.Canvas()Access the current test canvas
test.RenderObjectToMarkup(obj)Serialize widget tree to XML-like markup for snapshot tests
test.AssertNotificationSent(t, n, f)Assert a notification fires

lang package#

Internationalization support.

FunctionDescription
lang.Localize(in, ...data)Translate a string with optional template data
lang.LocalizeKey(key, fallback, ...data)Translate by explicit key
lang.LocalizePlural(in, count, ...data)Plural-aware translation
lang.AddTranslations(fyne.Resource)Load a JSON translation bundle
lang.AddTranslationsForLocale([]byte, fyne.Locale)Load translations for a specific locale
lang.AddTranslationsFS(embed.FS, dir)Load all translations from an embedded FS
lang.SystemLocale()Return the OS locale

Plugin / Extension system#

Fyne has five distinct extension points, all interface-based:

1. Custom widgets#

Implement fyne.Widget by embedding widget.BaseWidget (from the public widget package, not the internal one) and implementing CreateRenderer() fyne.WidgetRenderer. The renderer owns all child fyne.CanvasObject primitives and handles layout and refresh.

2. Custom themes#

Implement fyne.Theme (four methods: Color, Font, Icon, Size). Apply via app.Settings().SetTheme(myTheme). The theme package provides FromLegacy(LegacyTheme) for migration.

3. Custom URI repositories#

Implement storage/repository.Repository plus any capability sub-interfaces (WritableRepository, ListableRepository, etc.). Register via storage/repository.Register(scheme, repo). This lets libraries add new URI schemes (cloud storage, databases) that transparently work with storage.OpenFileFromURI, FileDialog, etc.

4. Cloud providers#

Implement fyne.CloudProvider and optionally CloudProviderPreferences and/or CloudProviderStorage. Set on the app via app.SetCloudProvider(provider). The provider’s Setup and Cleanup lifecycle hooks manage authentication; CloudPreferences/CloudStorage replace the local backends.

5. Custom embedded drivers (since 2.7)#

Implement driver/embedded.Driver for bare-metal / custom hardware deployments (e.g., Raspberry Pi framebuffer, custom display). Wire it in via app.SetDriverDetails. Examples of third-party backends are tracked in the fyne-x community repository.


API style#

  • Construction: Simple top-level New* constructor functions, not builder chains. NewButton("OK", fn) not ButtonBuilder{}.Label("OK").OnTap(fn).Build().
  • Callbacks: Assigned as exported function-typed struct fields (button.OnTapped = fn), not via AddListener/RemoveListener pairs. One callback per event per widget.
  • Data binding: Optional but pervasive. Any widget with user-facing state has a New*WithData(binding.X) variant.
  • No global registry: Widgets are not registered by name; they are instantiated directly.
  • Backward compatibility: // Since: X.Y comment markers on every addition since 1.4. // Deprecated: markers with migration targets. The v2 module path was the only breaking version change; within v2, backward compatibility has been maintained carefully (768 Since: annotations across the codebase, 982 Deprecated: occurrences, mostly in the deprecated cmd/fyne tool).