The latest news from the Fyne community

Keep up to date with everything we're working on and how the project is shaping up.

Find Out More



First Major Release

The first release of Fyne marks a milestone for the project. We now have a stable and performant base API. Moving forward we are excited to add new features and enhancements that have been requested over the months of development.

The main features of Fyne at this time are:

  • Canvas API (rect, line, circle, text, image)
  • Widget API (box, button, check, entry, form, group, hyperlink, icon, label, progress bar, radio, scroller, tabs and toolbar)
  • Light and dark themes
  • Pointer, key and shortcut APIs (generic and desktop extension)
  • OpenGL driver for Linux, macOS and Windows
  • Tools for embedding data and packaging releases

The entire toolkit is developed using scalable graphics so that it looks clean and crisp on different devices and screen densities. This release only supports desktop applications but watch this space :).

Get started today at

Building a Cross Platform GUI with Go

There are many tutorials available online for how to use web technologies and Go - but what if you want to create something in pure Go? Whether it’s for performance reasons, to keep all of your application in just one programming language or simply because you like Go over Javascript and HTML there are solutions available. Go bindings exist for GTK+, Qt, Windows, Nuklear and also platform abstraction bindings like andlabs UI.

In this tutorial we look at a newer approach - building a graphical application using a toolkit built specifically for go using a modern interpretation of the desktop user interface. The Fyne toolkit is a simple to learn graphical toolkit that we can use to build cross platform applications that will compile for macOS, Windows and Linux from the same code. We will explore how to get set up, write a basic application and then package it for distribution. Let’s get started!


The fyne toolkit communicates with operating system graphics using OpenGL, which is supported on almost all desktop and laptop systems. To do this it relies on the builtin functionality of Cgo, the C language bridge for Go. If you have not used this before you may need to install a C compiler as well as the usual Go tools.

The following sections provide an overview - more information is available in the Fyne Compiling documentation.


On macOS the XCode package provides this, but you will need to install the command line tools as well. If you have not already installed XCode you can do so from the Mac App Store. Once installed open a Terminal window and execute the command xcode-select --install to install the command line tools.


Various compiler packages are available on Windows. Any of Cygwin, MSYS2 and TDM-GCC should work. MSYS2 is usually the easiest to install - download the package and run it. Remember that to compile Fyne applications you will need to use the MSYS2 command prompt rather than the standard windows cmd or PowerShell.


On a linux system these tools may already be installed - if in doubt use your package manager to install the gcc and go (or golang) packages. Depending on your distribution it may be necessary to install the development headers for X11 and OpenGL which can usually be found in libgl1-mesa-dev and xorg-dev.

Installing Fyne

Setting up the Fyne API for use is as simple as downloading it using the go get command. The project is accessed from its base import name,

$ go get -u

Writing our first GUI

The basic Hello World application with Fyne is quite succinct. The entry point, app.New(), provided by the app sub-package, sets up a new application that we use to create a window. The widget sub-package defines the various widgets available that we can add to our new window:

package main

import (

func main() {
    a := app.New()
    win := a.NewWindow("Hello World")
        widget.NewLabel("Hello World!"),
        widget.NewButton("Quit", func() {

As you can see in the preceding code block, the newly created fyne.Window has its content set to a new widget.VBox that provides the basic layout. Into this we add a Hello World! label using widget.NewLabel() and a Quit button using widget.NewButton(). The second parameter to the button is a func() that will be called when the button is tapped.

Lastly, we call ShowAndRun() on the window we created. This function will show the window and start the application event loop. It is shorthand for win.Show(); app.Run().

Compiling and Running

In the usual manner you can either run the Go file directly or build it into a binary file that can be executed.

$ go run hello.go


$ go build hello.go
$ ./hello

Running the code should produce a simple app that looks like the following. Clicking the Quit button or closing the window will exit the application:

(running with the light theme - the default is dark, to change this set the FYNE_THEME environment variable)


In preparation for packaging an application it’s a good idea to have icons and other metadata (name, description, marketing content) to get an impact online. For this section we will skip these and show how to package a basic graphical application for local use, rather than distribution online or through an app store or market place.

Packaging a graphical application is usually more difficult than a command line or web-based application. End users expect to to see a familiar icon, to be able to have it in their application list and to install it simply by downloading or copying the executable file. This leads to many challenges including the management of metadata files and additional tools.

Thankfully Fyne has a tool that can help with application packaging (even if you’ve not used Fyne in your code). The fyne package command is designed to generate and package all the required metadata for an application to distribute on macOS, Linux, or Windows. By default it will build an application bundle for the current platform - but it could be used in part of a cross compilation workflow (more information in a future post).

Before executing this command the application should already be compiled for release (see go build above). There are many parameters that can change the contents of the resulting application, and the most useful will be the -icon parameter (which is required). The `fyne` command can be installed using:

$ go get

Once installed you can execute the fyne package command and check the output. On a macOS computer we will see it create a .app folder (known as an app bundle). To bundle this example we will use a temporary icon as a placeholder.

$ fyne package -icon blank_icon.png
$ ls
blank_icon.png	hello	hello.go
$ find

Looking at the result in Finder, we see the new directory as an application, its .app extension is hidden, and the icon is the same we set up before. You can launch, install, or remove this app like any other:

Executing the commands above on Windows or Linux would have created the appropriate application formats for each platform. These files could now be shared with anyone who has the same type of computer (that is, the operating system and CPU architecture match, as these are GOOS and GOARCH specific binary files).


In this article we saw how to get up and running with our first cross-platform native application written in Go. Whilst some tools had to be installed the code itself was simple and writing using pure Go means that the development environment can offer a lot of help in exploring the widgets available through autocompletion and inline documentation.

Stay tuned for future articles about the Fyne APIs, creation of custom widgets and cross-platform distribution.

I hoped you enjoyed reading this article. If you want to learn more about Go programming you should check out Hands-On GUI Application Development in Go. Packed with numerous real world examples it explores GUI libraries for Go including Go-GTK, Go-Qt, andlabs UI and Shiny to help you build beautiful, performant and responsive graphical applications.

2 Drivers and other Statistics

As GitHub recently emailed me with congratulations on 500 commits in Fyne I thought it was time for a quick review of statistics… The project has been under way now for 9 months and we have come a long way from the initial idea. In fact we have:

  • 500 Commits
  • 215 Star gazers
  • 13 Forks
  • 4 Contributors
  • 2 Drivers

What a few months it’s been! Yes the project is gaining momentum and we’re seeing cool new example apps - but the biggest news is the additional driver. We now have a fully functioning OpenGL based driver that can replace the EFL dependency.

If you don’t have EFL installed and/or can’t get it set up then we finally have an alternative. The new driver can be activated using the “gl” tag on any go run or build command for any Fyne based application

go run -tags gl .

This new driver has no external library dependencies which makes it far more portable. Applications built with this new driver will run happily on a different computer to the one it was built on.

Please give it a shot and raise any issues you find - this is going to be a fun new chapter in the Fyne story!

500 Commits

100 Stargazers

It’s been a while since posting on the Fyne blog so I thought I should update on progress. I went to the GitHub page to check the issues, pull requests and project status to see where everything was at. And then I noticed a much larger number than I remember in the repository summary.

Yup, it was the “Stargazers” number - how many GitHub users have starred the repository. We hit 100 when I wasn’t looking :). 8 months after the project started and there are 115 people have marked the project as one they are interested in. It may not be the largest number by any means, and there is a long way to go before we have got the engagement that we reckon can be achieved with this project… But hey - it’s faster than any other project I have worked on (including some larger community efforts too!).

So thanks everyone who is interested, come back often, get involved and let’s make something amazing together!

100 Stars

(image from kisspng)

Running on Gemini

Sorry there have not been many updated here recently - we are looking at lots of other GUI toolkits in Go to get inspiration for the best Fyne possible. Part of this project is looking at bundling, distribution and embedded platforms. And luckily my Gemini indigogo purchase just arrived!

And so I wanted to share with you the Fyne example application running on this fantastic piece of hardware. The base OS is Debian so there was not a log of adaptation necessary. With the next updated to the platform this should work out of the box, but for now it did require a little tweaking for old Go and EFL packages. We’re not sure if this backport is valuble to anyone or if the proof of concept is all we need to push forward toward the release date of the next Gemini Debian Linux release.

Fyne on Gemini

Please get in touch if you’d like to try it yourself and we can publish a branch and some instructions for getting it up and running :)

Drawing a Desktop

As part of our vision to create a beautiful desktop experience we have spent a lot of time setting up the new Fyne graphical toolkit. That project has got to a point now where we can start to use it’s capability to start work on the desktop we’ve been dreaming of! Not only is it part of our goals it is also a great way to test the graphical toolkit as it builds out.

Point and Click

At this stage it’s not much more than an interactive rendering - there is no ability to open windows and move them around, but we think it looks like a start. Check out the screenshot below - what you should be able to identify is a background pattern, mouse cursor and a toolbar that contains a handy clock, launchers and a quit button. Hopefully you like the screenshot below and can see the potential - if you’d like to join in please get in touch!

Fractal window

Desktop and testing

To launch in desktop mode this project uses the Linux DRM (Direct Rendering Manager) subsystem to draw directly to the screen when launched from a console. Once support for wayland window management is added this will be the basis for a true desktop environment.

Until then we wanted a way to test development more easily. If the program detects that it is running within X11 or a running wayland desktop then it loads in embedded mode. That means you can see the desktop in a smaller window in the current desktop. Pretty neat for quick feedback on your work :) (it also happens to be how the screenshot above was taken).

Fun with Fractals: Multithreading for Free!

One of the challenges of using (or writing) a GUI toolkit is concurrency and thread safety. It may not be immediately obvious but threads and concurrent execution are everywhere: you need a renderer to keep the interface looking correct, some event handling to manage user input, a main thread to control the lifecycle of the application and probably more… Even the simplest of apps - a hello world window with a quit button - would potentially spawn a thread to handle the click event.

Toolkits also have various restrictions that ensure things work correctly. For Example, iOS requires that code which updates the user interface is run on the application main thread. Similarly EFL asserts that graphical objects are owned by the main thread which can limit portability. In Fyne we aim to remove these restrictions for developers - it should be possible to influence the GUI from anywhere within an application and have the toolkit work out the rest!


To show off how easy threading is we’ve made a couple of examples - and the most interesting is a fractal renderer. As each pixel of a fractal image can be calculated independently it’s a perfect candidate for multi-threading. Thankfully Fyne has a helpful image type to set up a dynamic rendering - see the NewRaster documentation for the method signature. The renderer for this automatically splits the image into multiple regions that are handled by different threads.


If you want to see the content of the mandelbrot method then check the fractal source code. Running it locally should look something like this:

Fractal window

Async Interface Updates

To demonstrate how easy working with multiple application threads can be there is another little demo of a simple RSS reader. If you’re unfamiliar with why updating the user interface can be problematic take a look at this stack overflow thread or many others on the topic - we don’t want developers to worry about which thread their code is running on or how to communicate with the “UI thread”.

Now take a look at the blog example code which spawns a new go routine (this may run on a different thread, depending on many factors) that then updates the user interface. The relevant code is:

    func parse(url string, titleList *widget.List) {
    	feed := gofeed.NewParser().parseURL(url)

    	for i := range feed.Items {

    func main() {
    	url := ""

    	// ...	

    	list := widget.NewList()

    	go parse(url, list)


If you run the (full) example you will notice that the list of article titles gets populated after the user interface shows. The downloading and parsing of the feed takes a little time and that should not slow down the user interface. The bonus here is that they async code had no additional complications!

Looking for Contributors

Six weeks into the Fyne project and the basics are all in place! We were tracking the initial phases through the GitHub project Walking Skeleton and the tasks completed a short while ago. Since then the work has been focussed on documentation, the project roadmap and API documentation.

Now things are up and running there’s so much to do. Design, widgets, layout and a richer canvas are all needed to get to the first milestone “UI Toolkit”. With our outlined vision and the documentation in place it should be easy for new developers, designers and testers to get involved.

So we’re putting a shout out to Go developers, UI designers and anyone else interested in building a great new desktop environment to get in touch. For more details check out the contribute page on our website.

Platform Trifecta

You heard right - 3 platforms in only 3 weeks. Fyne now supports Linux, Mac OS X and Windows! Using the EFL for rendering has meant that getting up and running across multiple platforms has been possible even before our first milestone. Having all of them under our belt already means that we’re already in a good position to welcome developers from many backgrounds.

To show off the progress so far the examples repository has now got a calculator app. This works exactly as expected across all supported platfors (well it would - the code is identical!) and looks pretty decent as well. A basic colour scheme was loaded from the material design guidelines in 2 variants - light and dark. So any Fyne app can look great on a light or a dark themed desktop.

That’s everything for now, we leave you with these great screen grabs.

Calculator on Linux Calculator (light) on OS X Calculator (light) on Windows

The First 10 Days of Fyne

It’s been just 10 days since the Fyne project was announced and in that time we’ve had a lot of support! The IRC channel, which we added only a week ago, now has a core group of developers helping to discuss and guide the design of the toolkit. The website is up and running to help visitors understand what the project is about and see our progress. For the more developer oriented there is now a walking skeleton project which is tracking progress towards our first milestone.

In terms of a quick summary we have picked Go as the main language for development and API. The rendering pipeline we are using is EFL, though the details will be hidden completely from the Fyne APIs. Lastly we decided on the use of the Cassowary algorithm for layout - giving an experience similar to the iOS AutoLayout.

The Enlightenment IDE (Edi) has been updated for Go syntax and build lifecycle so anyone already working on EFL apps can continue using the same tooling for now :).

Happy coding and come back soon!

Get In Touch!

We're excited to hear from anyone interested in the project. Whether it's to find out more, provide suggestions or to get involved - drop us a line!

If you would like to join us on slack but are not yet signed up to the golang slack server you can request an invite.