Writing GUIs in Golang
This post will cover how you can write a user interface in Go. I’ll go over the different methods to code a UI, the available modules, and if you should even use Go for these types of applications.
Go isn’t usually thought of when creating a GUI application, but it is possible and I have written a few GUI applications myself with Go. The reason for it was that with Go I could quickly code all of my business logic and the GUI that was required for the problem was simple.
Should Golang be used for GUI Applications?
Honestly, writing a GUI application in Go is fine. For cross-platform applications, I’d suggest using Go bindings for GTK. There isn’t any added complexity compared to coding GTK in C, and the performance seems fine from my experience with writing business applications.
For why you may not want to use Go for GUI applications, there aren’t many. Coming from a C background, garbage collection in Go can be frustrating since I can’t free unused widgets and windows. Another reason is there isn’t as much support for GUIs in Go. I’ve only worked with simple programs that didn’t need OpenGL custom drawing, and regular widgets work well.
Golang GUI Options
Below are a few different methods you can use for writing a GUI in Go and the reasons for and against using them. It’s important to code your GUI separate from the rest of your code and employ a good programming pattern to keep your code organized. It’s crucial that you can update your models or GUI without having to rework other parts of your program.
Web Server Method
In this method, you’ll have your program start a web server using net/http
and use HTML, CSS, and text/template
to create a user interface (essentially a website). The Go application can then interact with the website UI using WebSockets or through ajax requests. It’s also possible to simply treat the program as a website and use forms on the site to process tasks.
Advantages
- All the modules are already available in Go
- HTML and CSS are fantastic markup languages.
- Quick and easy to get a GUI coded.
- Allows multiple users to access the program at once if made public.
Disadvantages
- You need to access your UI through a web browser.
- Your program goes from being written in Go to being written in Go, HTML, CSS, and possibly JavaScript.
- You’ll need to code either WebSockets or an API for the UI to interact with the program.
- Using hardware devices becomes challenging to integrate. For instance, having a barcode scanner will require you to read the serial connection from the Go application and then send a WebSocket request to the user’s webpage. Then you’ll need JavaScript to handle the event.
- The UI will lack basic window manager features. You’ll be unable to focus the window, prevent the window from being closed, and resizing the window automatically.
It’s probably best to avoid this method unless you are set on using HTML and CSS for your UI and don’t want additional libraries or the overhead of running an isolated browser. For some situations this method works perfectly.
HTML, CSS, and JavaScript with Isolated Browser
This method is the same as the Web Server method above, but you’ll use an isolated browser as your GUI. For instance, you could use Electron, Muon, Wails, Lorca, or another framework that allows HTML, CSS, and JavaScript to run as a desktop application. At this point, you should also consider coding the program in JavaScript.
Advantages
- HTML and CSS are fantastic markup languages.
- The program will be a traditional UI.
- Avoid WebSockets with JavaScript Bindings in some libraries compared to the Web Server method.
Disadvantages
- Adds extra complexity to the application because of multiple languages.
- The UI will still run a web browser as your UI.
- Performance is slower.
I’d rate this method higher than the Web Server method, primarily since you can code JavaScript bindings to avoid WebSocket and API nonsense. For traditional GUIs, view your options before settling on this method.
GTK Bindings
GTK bindings use the popular GTK library with Go bindings. GTK is verbose, but it’s no different than if you were to write it in C. As of 2021, gotk3 seems to be the most active module to use.
Advantages
- Cross-platform user interface.
- Less overhead since it doesn’t run external applications to render the user interface.
- The application can be written entirely in Go.
Disadvantages
- GTK takes a bit longer to write than HTML and CSS.
- Go’s garbage collection could keep windows and widgets allocated that you no longer need.
- GTK isn’t thread-safe.
I’ve written a few programs with GTK Go Bindings. Nothing too complex, just a few hundred widgets, controls, dialogs, and multiple windows. I find it works well. Keep in mind that GTK isn’t thread-safe, but there are many ways you can still run background tasks independently of the UI.
C Bindings
You could write your UI in C and then write the Go bindings to interact with the UI. I haven’t needed this amount of control of flexibility with C libraries yet. This method should work if you want to use Qt, GTK, Xlib, or even SDL without coding individual bindings for each of those libraries.
Advantages
- Lots of support from existing GUI libraries and different options available.
- The program will have good performance.
- The program will work as a traditional UI.
Disadvantages
- There will be additional code complexity.
This method would likely work well for applications with a complex GUI with many tasks that you want to code using Go. It’s worth considering writing the entire program in C.
Additional Libraries
Below are additional libraries that can be used to code GUIs in Golang. Some of these libraries have minimal support and activity and you should use vendoring if you decide to use them. It’s beneficial to create your own UI wrapper so you can swap out UI libraries in the future.
- go-gtk (deprecated): This is a module of Go bindings for GTK. It has been deprecated but has good examples.
- gotk3: This is a module of Go bindings for GTK. This module supports almost all GTK functions and has a good 1:1 mapping of function names.
- wxGo (deprecated): wxWidgets bindings for Go. This module hasn’t been updated since 2011.
- xgb: X bindings for Go. If you want to code a minimal UI library, this is probably a good starting point.
- x-go-binding: X Go Bindings.
- termbox-go: A pure Go implementation of termbox. This module is used to code a Terminal UI.
- andlabs/ui: A minimal library for coding UI that uses the
pkgui
C library. - gxui: Google’s experimental UI library for Go.
Wrap Up
Coding a UI in Go is fine. There are a lot of different ways to go about it each with its own advantages and drawbacks. Just don’t force yourself into using a language if there is a better language for the job.
My advice is to write your own wrapper and interfaces, then use one of the above libraries. This will make it much easier to use different UI libraries in the future since many of them don’t seem to have much support or activity.