Getting Started with Go Desktop — Installation to First App


What is Go Desktop?

Go Desktop refers to creating native desktop applications with the Go programming language using frameworks and toolkits that bind Go to native GUI libraries or provide cross-platform UI components. Popular options include:

  • Wails — builds lightweight native apps by combining Go backends with modern web frontends (React, Svelte, Vue).
  • Fyne — a pure Go UI toolkit that renders a native look across platforms.
  • Walk — Windows-only native GUI toolkit.
  • Lorca — tiny library that uses the system browser as the UI (Chromium/Chrome).

Each approach balances developer familiarity, app size, performance, and UI flexibility. This tutorial uses Fyne for a pure-Go experience and Wails for a brief note on web-based frontends later.


Prerequisites

  • Go 1.20+ installed and GOPATH/GOROOT set up properly.
  • Basic knowledge of Go syntax and modules.
  • A text editor or IDE (VS Code recommended).
  • For macOS and Linux: a C compiler and necessary system libraries (Fyne requires them for some features).
  • Optional: Node.js and package manager (npm/yarn) if you plan to use Wails with a web frontend.

Install Go

  1. Download the installer for your OS from the official Go website and follow the instructions.
  2. Verify installation:
go version 

You should see something like: go version go1.20 linux/amd64


Fyne is a modern, easy-to-use toolkit written in Go. It compiles to native binaries and supports theming, widgets, and layouts.

  1. Install fyne command-line tool:
go install fyne.io/fyne/v2/cmd/fyne@latest 
  1. Add Go bin to your PATH if not already (example):
export PATH=$PATH:$(go env GOPATH)/bin 
  1. Create a new project folder and initialize a module:
mkdir go-desktop-app cd go-desktop-app go mod init example.com/go-desktop-app 

Create Your First Fyne App

  1. Create main.go with the following content:
package main import (     "fyne.io/fyne/v2/app"     "fyne.io/fyne/v2/container"     "fyne.io/fyne/v2/widget" ) func main() {     a := app.New()     w := a.NewWindow("Hello Go Desktop")     label := widget.NewLabel("Welcome to Go Desktop with Fyne!")     button := widget.NewButton("Click me", func() {         label.SetText("Button clicked!")     })     w.SetContent(container.NewVBox(         label,         button,     ))     w.Resize(fyne.NewSize(400, 200))     w.ShowAndRun() } 
  1. Run the app:
go run . 

You should see a small window with a label and a button. Clicking the button updates the label text.


Build Cross-Platform Binaries

Fyne supports cross-compiling, but building for other OSes often requires the target OS’s toolchain or special environment variables.

  • Build for current OS:
go build -o hello-go-desktop 
  • Cross-compile for Linux/macOS/Windows (example: build Windows exe from Linux/macOS):
GOOS=windows GOARCH=amd64 go build -o hello-go-desktop.exe 

Note: GUI frameworks sometimes require additional steps or use of build servers for macOS .app bundles or code signing.


Packaging and Distribution

  • Windows: create an installer with tools like Inno Setup or NSIS.
  • macOS: build an .app bundle and sign/notarize if distributing publicly. Use fyne release tooling or create using goreleaser.
  • Linux: provide deb/rpm packages or AppImage/Flatpak for broader compatibility.

Consider using goreleaser to automate cross-platform builds and packaging:

brew install goreleaser/tap/goreleaser  # macOS example goreleaser init goreleaser release --snapshot --skip-publish --rm-dist 

Using Wails (if you prefer a web frontend)

Wails pairs Go backends with modern JS frontends. It’s suitable if you want richer UIs with web frameworks.

  1. Install Wails:
go install github.com/wailsapp/wails/v2/cmd/wails@latest 
  1. Create a new project:
wails init -n my-wails-app -t svelte cd my-wails-app wails build 

Wails generates a Go backend and a frontend scaffold you can develop with usual web tooling. The build command packages them into a native app.


Tips and Best Practices

  • Use modules (go.mod) to manage dependencies.
  • Keep UI logic separated from backend business logic.
  • For complex UIs, prefer Wails or a web-based frontend. For lightweight native apps, prefer Fyne.
  • Test on each target OS early to catch platform-specific issues.
  • Use CI (GitHub Actions, GitLab CI) + goreleaser for reproducible releases.

Example: Adding a File Dialog and Theme

Enhance the simple app with a file open dialog and theme switch:

package main import (     "fyne.io/fyne/v2"     "fyne.io/fyne/v2/app"     "fyne.io/fyne/v2/container"     "fyne.io/fyne/v2/dialog"     "fyne.io/fyne/v2/theme"     "fyne.io/fyne/v2/widget" ) func main() {     a := app.New()     w := a.NewWindow("Go Desktop Extended")     label := widget.NewLabel("No file selected")     openBtn := widget.NewButton("Open File", func() {         fd := dialog.NewFileOpen(func(r fyne.URIReadCloser, err error) {             if err == nil && r != nil {                 label.SetText(r.URI().String())                 r.Close()             }         }, w)         fd.Show()     })     themeBtn := widget.NewButton("Toggle Dark", func() {         if a.Settings().ThemeVariant() == theme.Dark {             a.Settings().SetThemeVariant(theme.Light)         } else {             a.Settings().SetThemeVariant(theme.Dark)         }     })     w.SetContent(container.NewVBox(         label,         openBtn,         themeBtn,     ))     w.Resize(fyne.NewSize(500, 200))     w.ShowAndRun() } 

Troubleshooting

  • If widgets don’t render, ensure you installed any required system packages (e.g., GTK on Linux).
  • On macOS, if the app crashes at runtime, check that you built on macOS for macOS to avoid code-signing issues.
  • For cross-compilation problems, use CI builders or Docker images configured for target OS toolchains.

Further Learning and Resources

  • Fyne docs and examples (browse repository and examples).
  • Wails documentation and template projects.
  • goreleaser for automated builds.
  • Community forums and GitHub issues for platform-specific help.

Congratulations — you’ve installed a Go desktop toolkit, written a simple GUI, and learned packaging basics. Continue by adding more widgets, persisting settings, and exploring OS integrations like notifications and tray icons.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *