Go is an extraordinary language commonly used for APIs and/or libraries. When someone thinks about graphical interfaces, he/she will probably use a built-in web server. However, there is a different approach that is gaining popularity. Wails is a technology that allows you to wrap both Go code and a web frontend into a single binary, making things simpler.
The purpose of this article is to get you acquainted with Wails by walking you through a simple example to show the CPU status in a graphical way. With this example, you will be able to understand the basic concepts and will have a new tool as an additional option whenever you need to build something similar.
What is Wails?
Wails is a framework that lets you write desktop apps using Go. The difference between Wails and other tools is that it exposes Go code to the frontend as functions that return promises. Wails is capable of this through a binding mechanism, which will be explained further on.
The frontend code can be developed using any common Javascript framework, e.g. Angular, React, Vue.js, and Vuetify.
Wails provides the ability to wrap both Go code and a web frontend into a single binary. The Wails Command Line Interface makes this process easier because it handles project creation, compilation, and bundling.
How do the Go Code and Javascript Framework Interact?
The interaction between the Go Code and Javascript happens through shared IPC (Inter-process communication). It works across the Javascript runtime and the Go runtime. Both runtimes provide a simple interface that hides the burden of dealing with the IPC mechanism directly. The developer can interact with the Binding and Event components.
https://wails.app/about/concepts/
Wails Binding
The Wails application provides a single method that exposes your Go code to the frontend. You can bind a function or a struct with exposed methods. At startup, Wails will analyze bound functions and provide the equivalent function in Javascript. This will allow the Go code to be directly called from Javascript.
The developer just needs to call the function in Javascript and will receive a promise back. If the call to the Go code is completed successfully, the result will be passed to the resolve function. If an error is returned, this will be passed to the reject function.
Wails Events
Wails has a unified event system similar to Javascript’s native event system. Each event sent either by Go or Javascript can be picked up on each side. Data may be passed along with any event.
Wails Installation
Prerequisites
- Go v1.12 or above
PATH environment variable should include the path to your ~/go/bin directory. You should also ensure Go modules are enabled with:
echo “export GO111MODULE=on” >> ~/.bashrc
npm
gcc + libraries (xcode-select --install)
Let’s Build an Application
We will build a desktop app using React and Go. It will be a very simple app to display the CPU usage of our machine in real-time.
How to Create a Project
Command:
wails init
Enter the project name and choose which Javascript framework you want to use.
For our example, we are going to use React. This will generate the following project structure and files:
If we want to run the code we just generated:
- To run the React front end:
~/Documents/GoCode/wails/cpustats-react/frontend:$ npm start
- To run the backend:
~/Documents/GoCode/wails/cpustats-react:$ wails serve
The application will run in the web browser at http://localhost:3000/. We will learn how to build it later. For testing and debugging purposes, we can code and check in the browser.
So now, how do we start reaping the benefits of using Wails for our project?
Binding Go Methods
To bind a Go method to be used in Javascript you should declare it in the following way:
Above, look at the method called basic. You will have to use the wails.CreateApp method with the desired configuration and then you will have to use the Bind() method to expose the method to the frontend.
Now, to call that method in Javascript you will have to use window.backend.methodName. Also, notice that this is a promise. See window.backend.basic() in the following example:
Binding Structs
Suppose you have a struct created in Go with the following method: GetCPUUsage. What this method does is use the gopsutil library to obtain the percentage of the machine’s CPU.
To call this struct method in Javascript, you will have to use window.backend.StructName.methodName. You can see in the example how the struct method is called: window.backend.Stats.GetCPUUsage(). In this case, we are just going to print the result in the console.
Binding Events
To bind an event you will use WailsInit. This is a method you will declare in the Go code. Look at how we declare an event called cpu_usage. The event will call the GetCPUUsage method every second.
To detect the event in Javascript we will use Wails.Events.On, capturing the event we created in Go, in this case cpu_usage.
In order to visualize the CPU usage graphically and with a radial bar, we use React graphs. To declare them, use the react-apexcharts library.
Building the project
The command used to build the project is wails build.
This will create our executable file: cpustats-react.
In addition, you can package the app using wails build -p.
This will generate an .app file, and in Mac, it will look like this:
The image for the app can be modified as well, by changing the appicon.png image.
When running, the desktop app will look like the following image. The CPU usage will be updated every second on the screen to reflect the corresponding percentage.
References
- Official Wails app page https://wails.app/
- Go CPU package https://godoc.org/github.com/shirou/gopsutil/cpu
- React charts library https://apexcharts.com/docs/react-charts/
KEY TAKEAWAYSAfter reviewing this simple example, we can conclude:
|